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.

In the article, the application's view is partitioned into a simple <Window> XAML and several <UserControl> elements. This structure is not arbitrary. In particular, my <Button> only worked once I restructured my application to be consistent with the aformentioned layout. Previously, my test project used a single <Window> control to represent the view.

I have a View (Reasons) that has a child view (SelectedQuestions). The selected questions has a datagrid on it. I need to notify the parent view Reasons when a selection is made and the row index of the datagrid on the SelectedQuestions view. When that selection is made in the SelectedQuestions view, the Reason view will enable buttons and populate other datagrids.

Are these routed commands what I am looking for to solve this? I am new to WPF and what direction to go with this issue.

Hi , one of the comments seems to indicate that this article is deprecated, in which case , what is it replaced with ? I am trying to bind commands to the View model and not the code behind and would like the easiest solution as is available in VS 2010 .

An ideal solution to my particular problem giving me the confidence to move on. Losing 1 mark because the source code contained some very relavent code which is missing from the article and confused me a little.

But then being new to WPF and MVVM I am easily confused at the moment.

Hey Josh - I've been reading lots about MVVM and your name comes up a lot. I appreciate that this article is probably deprecated, but I am struggling over some of the 'problems' that MVVM is attempting to solve - and thought this may be a good place to ask the questions..

Above you say:There are several distinct benefits in having the routed commands in the View talk directly to the ViewModel.

1. Bypassing the code-behind of the View means the View is that much less coupled to a ViewModel.
2. 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.
3. 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.
(my numbering)

1. I don't get this? Why does it mean that? Don't both the Xaml and C# code behind get compiled into a single class? Sure, having a direct reference in the code behind to an instance of the VM may be a little tightly coupled - but would not using an interface avoid very tight coupling - and be somewhat more robust than using what amount to magic strings in the Xaml?

2. What you say is true - but the VM is dependent on the View to properly handle a routed commend - I don't see the difference other than one is in Xaml and the other C# - the VM is dependent, in fact, on neither, as it is dependent on the object created using c# and Xaml

3. OK - I see that can be the case - although I think this drive to have no code-behind leaving us open to having issues with the designers relying on magic strings (e.g. the names of properties) which is gonna be harder to test than ensuring the view implements an interface (although there's no way I can think of to ensure the design uses the interface methods)

I'm not being critical of your work - I am just displaying my ignorance. I figure, with so many people looking at MVVM with WPF I'm just not getting it...

1. I don't get this? Why does it mean that? Don't both the Xaml and C# code behind get compiled into a single class? Sure, having a direct reference in the code behind to an instance of the VM may be a little tightly coupled - but would not using an interface avoid very tight coupling - and be somewhat more robust than using what amount to magic strings in the Xaml?

The magic strings in XAML is a pill one must swallow and accept. If the presence of magic strings is taken as an avoidable fact of life, my statement holds water. Otherwise, you're absolutely right that the coupling is merely being shifted from code to XAML. I suppose I had already swallowed that pill before writing this article.

_Maxxx_ wrote:

the VM is dependent, in fact, on neither, as it is dependent on the object created using c# and Xaml

The idea behind that statement was that declaring things in XAML is closer to foolproof/idiot-proof than writing code is. If you can declare in XAML some objects that do something, it's harder to mess it up compared to creating and configuring the same objects in code.

_Maxxx_ wrote:

although I think this drive to have no code-behind leaving us open to having issues with the designers relying on magic strings (e.g. the names of properties) which is gonna be harder to test than ensuring the view implements an interface (although there's no way I can think of to ensure the design uses the interface methods)

Perhaps I've been doing this too long, but I'm finding that pill very hard to swallow, given that I've spent half my life slapping junior programmers and students around (metaphorically!) for using magic strings!

I'm just one of those that always imagines the 'hidden code' behind these things-and in the case of magic strings it comes down to a loop doing string comparisons. ugh!

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"