Simplified MVVM Commanding with DelegateCommand
The MVVM (Model-Miew-ViewModel) pattern for WPF works really well, but for me has one big disadvantage – the sheer verbosity of it. There’s just so much code to type! Especially when you’re going for the ‘pure’ approach of no code in your code-behind.
One of the worst offenders for this is the Command model, whereby in your ViewModel you define a class which implements ICommand. This is made available to the View via a property, and when called, calls some method in your ViewModel.
(Note: This only applies to WPF. Silverlight doesn’t currently support commands in the same way.)
Here’s an example, from inside my ViewModel (MeasurementViewModel):
(This is set up in the XAML as follows:)
You can see the custom ICommand (AddDefinitionCommand), a local variable to hold it, and a property getter for the view to find it. Now considering that this doesn’t even have the code which performs the action (which is viewModel.AddMeasurementDefinition), that’s lot of overhead. And you have to do that for every single command! That’s button clicks, selection changes, and so on.
One of the problems is that the Command model provides a lot of flexibility by defining the CanExecute() method and CanExecuteChanged event, but I don’t need those in my simple scenario.
So, how to write a bit less code? Of course, you could make some good use of Code Snippets, but there are better solutions. The best one I’ve found is the DelegateCommand approach used in Microsoft’s Composite Application Library (a.k.a Prism), also discussed in Josh Smith’s MVVM article (where he calls it a RelayCommand). This involves defining an ICommand which uses delegates, and means you have less boilerplate code to write.
As I’m not interested in using the full features of the ICommand, my simple DelegateCommand goes like this:
And to call it, you simply need the following:
You can see the local member for the DelegateCommand, the ViewModel constructor where we define the method to call, and the property to make it available to the View. Much simpler, I’m sure you’ll agree!
Of course, if you want to include the rest of the Command functionality, you can just extend the DelegateCommand. So there you have it, all of your MVVM problems solved! Well, nearly..
(As I don’t seem to be able to upload DelegateCommand.cs for you to download, here’s the text for you to copy & paste. I’ll work WordPress out one of these days…)