MVVM - Commands, RelayCommands and EventToCommand
MVVM - Commands, RelayCommands and EventToCommand
Commands are an implementation of the ICommand interface that is part of the .NET Framework. This interface
is used a lot in MVVM applications, but it is useful not only in XAML-based apps. The ICommand interface
specifies three members:
The method Execute(object) is called when the command is actuated. It has one parameter, which can be used to pass
additional information from the caller to the command.
The method CanExecute(object) returns a Boolean. If the return value is true, it means that the command can be executed.
The parameter is the same one as for the Execute method. When used in XAML controls that support the Command
property, the control will be automatically disabled if CanExecute returns false.
The CanExecuteChanged event handler must be raised by the command implementation when the CanExecute method
needs to be reevaluated. In XAML, when an instance of ICommand is bound to a controls Command property through a
data-binding, raising the CanExecuteChanged event will automatically call the CanExecute method, and the control will be
enabled or disabled accordingly.
Note that in Windows Presentation Foundation (WPF), the CanExecuteChanged event does not need to be raised
manually. A class named CommandManager is observing the user interface and calls the CanExecute method
when it deems it necessary. In all other XAML frameworks, however (including Windows RT), the developer must
take care of raising this event when its needed.
Of course, having to implement the ICommand interface every time a command must be added to the project is
impractical. This is why some of the most popular frameworks and toolkits in .NET offer a generic
implementation of ICommand.
The RelayCommand
In the MVVM Light Toolkit, the open-source toolkit described in the previous articles in this series, the
ICommand implementation is called RelayCommand. The constructor of this class has two parameters:
The first parameter is compulsory. It is used for the Execute method that the ICommand interface requires. For example, a
lambda expression can be used as shown in Figure 3. Alternatively, the syntax shown in Figure 2 can be used, where a
delegate to a method is provided for the Execute parameter.
The second parameter is optional. It is a delegate for the CanExecute method thats specified by ICommand. This delegate
must return a Boolean. Here, too, a lambda expression can be used, as shown in Figure 2, as can a delegate to a method
defined somewhere else.
Figure 2. Creating a RelayCommand
1. public RelayCommand MyCommand
2. {
3. get;
4. private set;
5. }
6.
7. public MainViewModel()
8. {
9. MyCommand = new RelayCommand(
10. ExecuteMyCommand,
11. () => _canExecuteMyCommand);
12. }
13.
14. private void ExecuteMyCommand()
15. {
16. // Do something
17. }
The code in Figure 3 shows a more compact syntax for a RelayCommand, accepting a parameter of type
RssArticle. This example is taken from the RssReader sample application that was implemented in the previous
articles. The code in the property getter checks first (thanks to the ?? operator) whether the
_navigateToArticleCommand attribute is already created. If yes, the attribute is returned. If not, the command is
created and stored in the attribute before it is returned. The command takes one parameter of type RssArticle,
as specified by the generic parameter in the command declaration. In XAML, as we will see later in Figure 9, the
parameter can be specified with any XAML expression, such as a Binding, a StaticResource or an explicit value; in
that last case (for example True, 1234.45, or Hello world), the RelayCommand will attempt to convert the
value (specified as a string in the XAML markup) to the type specified in the RelayCommand declaration. This
conversion might fail if no converter is found in the system by the XAML parser or if the value is invalid.