Команда маршрутизации и реле MVVM

В чем разница между RoutedCommand и RelayCommand ? Когда использовать RoutedCommand и когда использовать RelayCommand в шаблоне MVVM?

RoutedCommand является частью WPF, а RelayCommand был создан учеником WPF Джошем Смитом;).

Серьезно, однако, RS Конли описал некоторые различия. Основное различие заключается в том, что RoutedCommand – это реализация ICommand, которая использует RoutedEvent для маршрутизации через дерево до тех пор, пока не будет найдено CommandBinding для команды, в то время как RelayCommand не выполняет маршрутизацию и вместо этого непосредственно выполняет какой-либо делегат. В сценарии MV-VM RelayCommand (DelegateCommand in Prism), вероятно, лучший выбор.

Что касается использования RelayCommand и RoutedCommand в MVVM, основное отличие для меня заключается в следующем:

Расположение кода

RelayCommand позволяет реализовать команду в любом classе (как ICommand-свойство с делегатами), который затем условно привязывается к элементу управления, который вызывает команду. Этот class является ViewModel . Если вы используете маршрутизированную команду, вам придется реализовать методы, связанные с командой в коде управления элемента управления, потому что методы задаются атрибутами элемента CommandBinding. Предполагается, что строгий MVVM означает наличие «пустого» кода-кода, на самом деле нет возможности использовать стандартные маршрутизированные команды с MVVM.

Что RS Конли сказал, что RelayCommand позволяет вам определить RelayCommand за пределами ViewModel, это правильно, но в первую очередь это позволяет определить его внутри ViewModel, которого нет в RoutedCommand.

маршрутизация

С другой стороны, RelayCommands не поддерживают маршрутизацию через дерево (как было сказано ранее), что не является проблемой, если ваш интерфейс основан на одном viewModel. Если это не так, например, если у вас есть коллекция элементов со своими собственными viewModels и вы хотите вызвать команду дочернего ViewModel для каждого элемента из родительского элемента сразу, вам придется использовать маршрутизацию (см. Также CompositeCommands) ,

В целом, я бы сказал, что стандартные RoutedCommands не могут использоваться в строгом MVVM. RelayCommands идеально подходят для MVVM, но не поддерживают маршрутизацию, которая вам может понадобиться.

Разница в том, что RelayCommand может принимать делегатов. Вы можете определить RelayCommand вне ViewModel. Затем ViewModel может добавлять делегатов в команду, когда он создает и связывает команду с объектом пользовательского интерфейса, например с элементом управления. Делегаты, в свою очередь, могут получить доступ к частной переменной ViewModel, поскольку они определены в области самой модели просмотра.

Он используется для сокращения количества кода, содержащегося в ViewModel, поскольку тренд заключается в определении команды Routed как вложенного classа внутри ViewModel. Функциональность этих двух аналогична.

Я бы сказал, что RoutedCommands совершенно законны в строгом MVVM. Хотя RelayCommands часто предпочтительнее для их простоты, RoutedCommands иногда предлагают организационные преимущества. Например, вам может потребоваться несколько разных представлений для подключения к общему экземпляру ICommand без непосредственного отображения этой команды в базовые ViewModels.

В качестве примечания следует помнить, что строгий MVVM не запрещает использование кода. Если это так, вы никогда не сможете определить свойства пользовательской зависимости в своих представлениях!

Чтобы использовать RoutedCommand в строгой структуре MVVM, вы можете выполнить следующие действия:

  1. Объявите статический экземпляр RoutedCommand для вашей пользовательской команды. Этот шаг можно пропустить, если вы планируете использовать предопределенную команду из classа ApplicationCommands. Например:

    public static class MyCommands { public static RoutedCommand MyCustomCommand = new RoutedCommand(); } 
  2. Прикрепите нужные виды к RoutedCommand с помощью XAML:

      
  3. Один из ваших взглядов, привязанный к подходящей ViewModel (то есть, какой бы ViewModel не реализовал функциональность команды), необходимо выставить настраиваемый DependencyProperty, который будет связан с реализацией ViewModel:

     public partial class MainView : UserControl { public static readonly DependencyProperty MyCustomCommandProperty = DependencyProperty.Register("MyCustomCommand", typeof(ICommand), typeof(MainView), new UIPropertyMetadata(null)); public ICommand MyCustomCommand { get { return (ICommand)GetValue(MyCustomCommandProperty); } set { SetValue(MyCustomCommandProperty, value); } } 
  4. Тот же вид должен привязываться к RoutedCommand с шага 1. В XAML:

        

    В коде для вашего просмотра связанные обработчики событий просто делегируют ICommand из свойства зависимостей, объявленного в шаге 3:

     private void MyCustomCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e) { var command = this.MyCustomCommand; if (command != null) { e.Handled = true; e.CanExecute = command.CanExecute(e.Parameter); } } private void MyCustomCommand_Executed(object sender, ExecutedRoutedEventArgs e) { var command = this.MyCustomCommand; if (command != null) { e.Handled = true; command.Execute(e.Parameter); } } 
  5. Наконец, привяжите реализацию команды ViewModel (которая должна быть ICommand) к свойству пользовательской зависимости в XAML:

      

Преимущество такого подхода заключается в том, что ваш ViewModel должен обеспечить единую реализацию интерфейса ICommand (и это может быть даже RelayCommand), в то время как любое количество Views может присоединяться к нему через RoutedCommand, не требуя непосредственной привязки к этому ViewModel.

К сожалению, есть недостаток в том, что событие ICommand.CanExecuteChanged не будет работать. Когда ваш ViewModel хочет, чтобы View обновил свойство CanExecute, вы должны вызвать CommandManager.InvalidateRequerySposed ().

  • команды в java для очистки экрана
  • Как выполнить команду на удаленном компьютере?
  • Давайте будем гением компьютера.