What is the Difference between the RoutedCommand and RelayCommand ? When to use RoutedCommand and when to use RelayCommand in MVVM pattern ?
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:
public static class MyCommands {
public static RoutedCommand MyCustomCommand = new RoutedCommand();
}
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:
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); }
}
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:
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);
}
}
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().