What is the Difference between the RoutedCommand and RelayCommand ? When to use RoutedCommand and when to use RelayCommand in MVVM pattern ?
相关问题
- ObservableCollection in ViewModel is not updated w
- Is it possible to send a List<Object> in MVV
- How to make an element reference a StaticResource
- Override yml configuration in spring-boot with com
- Get the selected items of a ListView (MVVM, Calibu
相关文章
- Best way to implement MVVM bindings (View <-> V
- Using LiveData to set visibility of TextView
- app:visibleGone cannot resolve on android Databind
- PowerShell Pass Named parameters to ArgumentList
- Adb install progress bar
- Bash Centos7 “which” command
- Command binding Unable to cast object of type '
- WPF MVVM two-way updates
RoutedCommand is part of WPF, while RelayCommand was created by a WPF Disciple, Josh Smith ;).
Seriously, though, RS Conley described some of the differences. The key difference is that RoutedCommand is an ICommand implementation that uses a RoutedEvent to route through the tree until a CommandBinding for the command is found, while RelayCommand does no routing and instead directly executes some delegate. In a M-V-VM scenario a RelayCommand (DelegateCommand in Prism) is probably the better choice all around.
I would argue that RoutedCommands are perfectly legal in strict MVVM. Although RelayCommands are often preferable for their simplicity, RoutedCommands sometimes offer organizational advantages. For example, you might want several different views to connect to a shared ICommand instance without directly exposing that command to the underlying ViewModels.
As a side note, remember that strict MVVM does not prohibit the use of code-behind. If that were true then you could never define custom dependency properties in your views!
In order to use a RoutedCommand within a strict MVVM framework you could follow these steps:
Declare a static RoutedCommand instance for your custom command. You can skip this step if you plan to use a predefined command from the ApplicationCommands class. For example:
Attach the desired views to the RoutedCommand using XAML:
One of your views which is bound to a suitable ViewModel (i.e. whichever ViewModel implements the command functionality) needs to expose a custom DependencyProperty which will be bound to your ViewModel's implementation:
The same view should bind itself to the RoutedCommand from step 1. In the XAML:
In the code-behind for your view the associated event handlers will just delegate to the ICommand from the dependency property declared in step 3:
Finally, bind your ViewModel's command implementation (which should be an ICommand) to the custom dependency property in XAML:
The advantage of this approach is that your ViewModel only needs to provide a single implementation of the ICommand interface (and it can even be a RelayCommand), while any number of Views can attach to it via the RoutedCommand without needing to be directly bound to that ViewModel.
Unfortunately there is a downside in that the ICommand.CanExecuteChanged event will not work. When your ViewModel wants the View to refresh the CanExecute property then you must call CommandManager.InvalidateRequerySuggested().
The difference is that RelayCommand can accept delegates. You can define the RelayCommand outside of the ViewModel. The ViewModel can then add delegates to the command when it creates and binds the command to an UI object like a control. The delegates in turn can access the private variable of the ViewModel as they are defined in the scope of the View Model itself.
It is used to cut down on the amount of code contained in the ViewModel as the trend is to define a Routed command as a nested class inside the ViewModel. The functionality of the two is otherwise similar.
Regarding the use of RelayCommand and RoutedCommand in MVVM the main difference for me is the following:
Location of code
RelayCommand allows you to implement the command in any class (as ICommand-property with delegates), which then is conventionally databound to the control, which invokes the command. This class is the ViewModel. If you use a routed command, you will have to implement the methods related to the command in the codebehind of the control, because the methods are specified by the attributes of the CommandBinding-element. Assumed that strict MVVM means having an "empty" codebehind-file, there actually is no possibility of using standard routed commands with MVVM.
What RS Conley said, that RelayCommand allows you to define the RelayCommand outside the ViewModel is right, but first of all it allows you to define it inside the ViewModel, which RoutedCommand doesn't.
Routing
On the other hand, RelayCommands do not support routing through the tree (as said before), which is not a problem, as long as your interface is based on a single viewModel. If it is not, for example if you have a collection of items with their own viewModels and want to invoke a command of the child ViewModel for each item out of the parent element at once, you will have to use routing (see also CompositeCommands).
All in all, I would say, that standard RoutedCommands are not usable in strict MVVM. RelayCommands are perfect for MVVM but do not support routing, which you might need.