Introduction

This article examines a technique that makes it easy to use routed commands when the command execution logic resides in ViewModel objects. This approach cuts out the middleman; the code-behind file. It allows your ViewModel objects to be the direct recipient of routed command execution and status query notifications.

Background

There was an interesting thread on the WPF Disciples forum about how to use routed commands in conjunction with the Model-View-ViewModel pattern. After much discussion, and a side conversation with Bill Kempf, I began to understand what the core issue was. Most examples of using WPF with the MVP, MVC, or MVVM patterns involve the use of routed commands. Those commands are accompanied by CommandBindings that point to event handling methods in the code-behind of the View, which, in turn, delegate to the Presenter/Controller/ViewModel associated with that View. The thread on the WPF Disciples forum revolved around a search to find a way for those RoutedCommands to talk directly to the ViewModel.

The Benefits

There are several distinct benefits in having the routed commands in the View talk directly to the ViewModel. Bypassing the code-behind of the View means the View is that much less coupled to a ViewModel. It also means that the ViewModel is not dependent on the View’s code-behind to properly handle a routed command’s events and delegate those calls off to the correct members on the ViewModel objects. Not only that, but it reduces the amount of coding required to create a View, which is important when working in the Designer-Developer workflow.

Prior Art

There are several existing solutions to this type of problem out there, from Dan Crevier’s CommandModel to Rob Eisenberg’s Caliburn framework. I felt that CommandModel was too complicated and restrictive, while Caliburn was too heavy and broad. I am not saying that they are in any way bad solutions, just not what I wanted for this particular task.

My Solution

I thought long and hard about the issue, and decided that the solution is to create a custom CommandBinding class. To that end, I created the CommandSinkBinding class. It has two CommandSink properties: one is a normal instance property, the other is an attached property. The instance property provides a CommandSinkBinding with an object to handle its CanExecute and Executed events. The attached CommandSink property is used to specify the command sink to give to every CommandSinkBinding in an element’s CommandBindings collection.

The other piece of the puzzle is a small interface called ICommandSink and a class that implements the interface, named CommandSink. The ViewModel classes that want to react to routed commands must implement that interface, or derive from CommandSink.

This solution is very lightweight, reusable, and does not rely on the use of Reflection at all.

Seeing it in Action

Before we examine how my solution works, let’s first take a look at the demo app, which is available for download at the top of this article. When you run the demo, it looks like this:

The UI shows three people, each of which you can tell to speak and die. If you click a person’s Speak button, a message box pops up like so:

If you click a person’s Die button, they become disabled and grey, as seen below:

The main Window’s code-behind file is unaltered. The content of its XAML file is listed below:

Clearly, there is not much going on in the Window. Let’s now move our attention to the content of the Window: the CommunityView control. This user control knows how to render a CommunityViewModel object, which is basically just a container of PersonViewModel objects and a command that allows you to kill them all in one fell swoop.

We will examine the ViewModel classes later, but for now, here is the CommunityView control. It is important to note that the code-behind file of the CommunityView and PersonView controls have no code in them, aside from the auto-generated code that calls the standard InitializeComponent.

The most relevant parts of that XAML is bold. As you can see, this control’s CommandBindings contains a CommandSinkBinding whose Command property references a static command of the CommunityViewModel class. The Kill All button also references that command. Notice how the UserControl element has the CommandSinkBinding’s CommandSink attached property set to {Binding}. That means, it is bound to the DataContext of the CommunityView control, which is the CommunityViewModel object set on the main Window’s DataContext, as seen previously.

Each PersonViewModel in the community renders in an ItemsControl. That control’s ItemsSource is bound to the People property of the CommunityViewModel object, which is the data context. Each item in the control is rendered by a DataTemplate which emits a PersonView control. Now, let’s see PersonView’s XAML file:

Aside from having more stylistic resources and visual elements, this control is essentially the same as the CommunityView control. It, too, has CommandSinkBindings in its CommandBindings collection, it has the CommandSink attached property set on it, and the buttons it contains have their Command property set to static command fields of a ViewModel class. When the commands in this control execute, they will be handled by logic in the PersonViewModel class, instead of the CommunityViewModel class. That makes sense, considering this is a View of the PersonViewModel class.

Once again, it is important to note that the code-behind file of the CommunityView and PersonView controls have no code in them, aside from the auto-generated code that calls InitializeComponent. The main Window’s code-behind file is also unaltered. If you are accustomed to working with routed commands, this might seem both strange and wonderful at the same time!

How it Works

Now it is time to turn our attention to how this works. You do not have to read this section of the article in order to use my solution, though I strongly recommend you do for the sake of understanding.

ICommandSink

First, we will examine the ICommandSink interface. Remember, this is the interface that the ViewModel classes implement; it is implemented by the CommandSink class, and it is the type of the CommandSink property of CommandSinkBinding.

///<summary>/// Represents an object that is capable of being notified of
/// a routed command execution by a CommandSinkBinding. This
/// interface is intended to be implemented by a ViewModel class
/// that honors a set of routed commands.
///</summary>publicinterface ICommandSink
{
bool CanExecuteCommand(ICommand command, object parameter, outbool handled);
void ExecuteCommand(ICommand command, object parameter, outbool handled);
}

This is similar to the standard ICommand interface signature, only it is intended to be implemented by a class that can work with multiple commands. I included the handled parameter in both methods because I use it to set the Handled property of the event argument passed into a CommandSinkBinding’s event handling methods. Be sure to set that argument to true if your logic has successfully completed executing the command logic, or provide an execution status, because it helps improve performance in situations where there are large element trees and many routed commands.

CommandSinkBinding

The real meat is in the CommandSinkBinding class. The class declaration and the instance CommandSink property is below:

It is important to note that setting the attached CommandSink property only has an effect once for an element. You cannot set it again, nor set it to null. If you subsequently add a CommandSinkBinding to that element’s CommandBindings, you will have to explicitly set that object’s CommandSink property to an ICommandSink object. The CommandBindingCollection class does not provide collection change notifications, so I have no way of knowing if or when new items are added to the collection.

CommandSink

Now that we have seen the fundamental pieces of the solution, let's turn our attention to a very convenient class called CommandSink, which implements the ICommandSink interface seen above. This class was suggested to me by the brilliant Bill Kempf shortly after I published this article. It provides a consolidated, reusable way to cleanly implement ViewModel objects that use this pattern. It can be used as a base class for your ViewModel objects, or, if you already have a base class for your ViewModel, you can embed an instance of CommandSink into a ViewModel class. I suggest you derive your ViewModel classes from CommandSink if possible, because it results in less code you have to write and maintain.

Using CommandSink in ViewModel Classes

Finally, it is time to see how to use CommandSink in a ViewModel class. Let’s see how the CommunityViewModel class is defined. Remember, this class is the ViewModel object assigned to the main Window’s DataContext property.

The magic occurs in the constructor. Notice the call to the RegisterCommand method, which is defined by the CommandSink base class. The first argument is the command being registered. The second argument is a Predicate<object>, created as a lambda expression, which is invoked when the command is queried to see if it can execute. The last argument is an Action<object>, created as a lambda expression, which is invoked when the command executes. Naturally, the use of lambda expressions is optional.

Now, let's see how the PersonViewModel class works. It is an example of embedding CommandSink, instead of deriving from it. Since PersonViewModel does not derive from CommandSink, it must implement the ICommandSink interface instead.

I won't bother showing you every member of the class, since they are not very important for this review. We will, however, now see how PersonViewModel implements the ICommandSink interface and how it uses an instance of the CommandSink class.

Revision History

July 26, 2008 – Made several improvements to the solution, including: took Bill Kempf's advice and created the CommandSink class, updated the ViewModel classes to use it, renamed RelayCommandBinding to CommandSinkBinding, and fixed CommandSinkBinding so that it works for elements in a template. Updated the article and source code download.

My problem with this approach is also my problem with the rather crude Microsoft ICommand scheme, it really is not very clear or flexible. I think that what is needed is something similar to the Binding for data, in fact the same syntax could be used. The ICommand mixes two functions, which I think is wrong. The CanExecute is actually a very good idea, but why not use existing data binding syntax to set the enabled property. Might even what to extend the concept of the ICommand to include more than just the Execute and CanExecute for the button, have the option to include other button attributes such as tooltip and caption to support internationalization also. Anyway I think that there should be a new concept for events where any event can use binding whose implementation would be similar to the current data binding, but would support events instead. The current concept only supports click events, and there are other events which it is often great to be able to support in the MVVM environment. In fact if I could just bind to the state of the button (pushed, not pushed), I could provide a lot of the functionality using databinding. what I would not have is the ability to include parameters. Now if I could do something like this in XAML, I think it may go a long way to simplifying for the developers the MVVM:

I have a window which contains a TabControl. I've set it up such that each TabItem has its own VM. DataBinding is working fine, but Commanding via the CommandSinkBinding only works if I register for those commands on a VM assigned as the DataContext of the entire Window. Any ideas off the top of your head?

I have a similiar problem where my tabsitems are controls in a seperate project. I have implemented the commandsink in the controls themselves and do the CommandSinkBinding.CommandSink="{Binding}" at the control level, but all is greyed out.

Are you suggesting that I have my commandsink at the window level, but add the CommandSinkBinding.CommandSink="{Binding}" in each tabitem?

I'm not really sure if this is the correct place to ask this question , but maybe you can help me out.
I'm creating all ribbon stuff(tab, group, controls) dynamically by code behind. I want to fill all tabs and groups from database. But when i wanted to set the LabelTitle, ToolTipTitle, and ToolTipDescription for the RibbonButton, i noticed that they must go in a RibbonCommand and then set that Command to the Button. right?. When i do it by xaml there is no problem. But when i do it on code behind , the labelTitle appears, but the RibbonButton is disabled. I read something about this problem, and it says that RibbonCommand needs to have Execute and CanExecute. My question is, how can i deal with that by code behind.
I'm sorry if this is a easy question , but i'm learning WPF and this new control.

Here is my code:

'TAB
Dim rbnTab As New RibbonTab
rbnTab.Label = "Orders"

'GROUP
Dim rbnGroup As New RibbonGroup

'COMMAND FOR THE GROUP
Dim rbnGroupCommand As New RibbonCommand
rbnGroupCommand.LabelTitle = "Grower Order"

Is there any examples where RoutedCommands are used for multiple instances of the same view and viewmodel?

I think the greatest advantage of RoutedCommands is the notion of a context.
Example:
Top level menu Command="Cut"
If there is a TextBox on your view and some text is selected in it a user can use the top level menu to cut the text in the textbox.
And if the model view have

The top level menu 'Cut' would both work for a text selected in a text box and fire the CommandHandlerCut if any other control have focus i.e a button.
Questions:
Does the code above breaks MVVM pattern? Should viewmodel be completely unaware about its view. including type? How about using typeof(Control)?

tabcontrol tabitems are also generated with a template.
The only difference from the original article: I use RoutedCommands. For some reason if I use the RegisterClassCommandBinding as shown above the commands are always routed to the first tab view model. Any idea why?
I.e. if I created several tabs and each of them created a command binding in the viewmodel as shown above all of them are handeled by the first tab page viewmodel. If I create a simple application that does not use DataTemplate and ItemTemplates it works. Tryed to use attached properties - does not work. i.e.

Hi Josh,
I think you've undersold the awesomeness of what you've done here. It is flexible in that it appears to make it easy to add input bindings and stock commands to commands handled by a view model. My question is how can a command get added at the top application menu level that applies to the currently selected person? By example I've added a "Scythe Menu" and some keyboard shortcuts as explained below. The "Kill All" menu and "Ctrl+K" gestures work. The "Del" gesture works. The "Delete" menu does not. Why not? I tried setting FocusManager.IsFocusScope on the CommunityView to no avail. What is the best way to do something like this with MVVM?

(look at ExecutedHandlerExtension and CommandBindingAdapter classes). The solution uses the attached property which mimic the commandBinding collection. The actual bindings are added using the markup extention ( this way you can supply both the command target and handler ). The CommandBinding collection is filled internally in attached property change callback. Pretty simple and elegant - also seems to support the RibbonCommands as well as Routed(UI)Commands.