Подтвердить что ты не робот

Почему RelayCommand

Я много программировал в WPF, но мои View и ViewModel не являются отдельными на данный момент. Ну, это частично. Все привязки, связанные с текстом в текстовых полях, содержимым для ярлыков, списками в datagrids,... выполняются с помощью обычных свойств с событием NotifyPropertyChanged в них.

Все мои события для обработки щелчков кнопок или текстовых изменений выполняются путем связывания событий. Теперь я хотел начать работу с командами и нашел эту статью: http://www.codeproject.com/Articles/126249/MVVM-Pattern-in-WPF-A-Simple-Tutorial-for-Absolute. В нем есть объяснение того, как настроить MVVM, но меня путают с RelayCommand.

Какая работа? Может ли он использоваться для всех команд в моей форме? Как отключить кнопку, если (a) не заполнено определенное текстовое поле?


ИЗМЕНИТЬ 1:

Хорошее объяснение: "Используется ли оно для всех команд в моей форме?" здесь отвечает: qaru.site/info/238856/...

Вот код, который у меня есть до сих пор: https://stackoverflow.com/a/22289358/3357699

4b9b3361

Ответ 1

Команды разделяют семантику и объект, который вызывает команду из логики, которая выполняет команду, то есть она отделяет компонент пользовательского интерфейса от логики, которая должна выполняться при вызове команды. Итак, вы можете тестировать бизнес-логику отдельно, используя тестовые примеры, а также ваш код пользовательского интерфейса слабо связан с бизнес-логикой.

Теперь, когда вы говорите, задавайте свои вопросы один за другим:

Какую работу он выполняет?

Я добавил подробности выше. Надеюсь, он очистит использование команд.


Может ли он использоваться для всех команд в моей форме?

В некоторых элементах управления отображаются команды DependencyProperty, такие как Button, MenuItem и т.д., которые имеют определенное событие по умолчанию, зарегистрированное для него. Для Button это событие Click. Итак, если вы привязаете ICommand, объявленный в ViewModel, с помощью кнопки Command DP, он будет вызываться всякий раз, когда нажимается кнопка.

Для других событий вы можете связать с помощью Interactivity triggers. Обратитесь к образцу здесь, как использовать их для привязки к ICommand в ViewModel.


Как отключить кнопку, когда (a) определенные текстовые поля не являются заполнено?

Ссылка, которую вы опубликовали, не обеспечивает полную реализацию RelayCommand. Ему не хватает перегруженного конструктора для установки предиката CanExecute, который играет ключевую роль в включении/отключении элемента управления пользовательского интерфейса, к которому привязана ваша команда.

Связывание текстовых полей с некоторыми свойствами в ViewModel и в CanExecute делегирование возвращает false, если какое-либо из связанного свойства равно null или пустое, что автоматически отключает элемент управления, к которому привязана команда.


Полная реализация RelayCommand:

public class RelayCommand<T> : ICommand
{
    #region Fields

    readonly Action<T> _execute = null;
    readonly Predicate<T> _canExecute = null;

    #endregion

    #region Constructors

    /// <summary>
    /// Initializes a new instance of <see cref="DelegateCommand{T}"/>.
    /// </summary>
    /// <param name="execute">Delegate to execute when Execute is called on the command.  This can be null to just hook up a CanExecute delegate.</param>
    /// <remarks><seealso cref="CanExecute"/> will always return true.</remarks>
    public RelayCommand(Action<T> execute)
        : this(execute, null)
    {
    }

    /// <summary>
    /// Creates a new command.
    /// </summary>
    /// <param name="execute">The execution logic.</param>
    /// <param name="canExecute">The execution status logic.</param>
    public RelayCommand(Action<T> execute, Predicate<T> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }

    #endregion

    #region ICommand Members

    ///<summary>
    ///Defines the method that determines whether the command can execute in its current state.
    ///</summary>
    ///<param name="parameter">Data used by the command.  If the command does not require data to be passed, this object can be set to null.</param>
    ///<returns>
    ///true if this command can be executed; otherwise, false.
    ///</returns>
    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute((T)parameter);
    }

    ///<summary>
    ///Occurs when changes occur that affect whether or not the command should execute.
    ///</summary>
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    ///<summary>
    ///Defines the method to be called when the command is invoked.
    ///</summary>
    ///<param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to <see langword="null" />.</param>
    public void Execute(object parameter)
    {
        _execute((T)parameter);
    }

    #endregion
}

Ответ 2

Преимущество использования команды relay заключается в том, что вы можете привязывать команды непосредственно к ViewModels. Используя команды таким образом, вы избегаете писать код в кодах вида.

При использовании команд реле вам необходимо будет предоставить два метода. Первый из них дает значение, может ли команда быть выполнена (например, "CanExecuteSave" ), а другая отвечает за выполнение команды ( "ExecuteSave" ).