I've got to be honest and admit up front that initially I wasn't completely sold on the idea that WPF Commands are the great leap forward that they are sometimes billed as. OK, so I get that they can reduce the repetition of event handling code, but even their most ardent supporters aren't going to be able to claim that the required code is particularly intuitive. I will agree though that the availability of CanExecute is useful sometimes when multiple controls are bound to a Command. As a WinForms developer moving to WPF, I still find that in many cases I'm happy to use event handlers and, where necessary, a utility method or two.
So, having got that caveat out of the way, let's look at a basic situation where we want a range of different user actions to trigger the same task.
I've decided to use the scenario that I covered in this blog. It's maybe not the most realistic scenario, but it does give an opportunity to use a wide range of user inputs and gestures to move the image across the screen. It also allows the use of the CanExecute event.
In the earlier blog, the user had to click on an image to make it move from left to right across a Canvas. This can soon become tiresome, so by means of a Command we'll give her several other options. In order to make the use of CanExecute realistic, we will say that once the image reaches the far right edge of the Canvas, it must stay there. So the image move will be allowed to happen (i.e. CanExecute) as long as it hasn't reached the right hand edge of the canvas.
Creating the User Interface
The following XAML will create an updated version of the Canvas-and-Image UI used previously. This version includes various controls that will be bound to the Command.
<Window x:Class="Window3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Using A Command" Height="300" Width="300">
<Grid x:Name="MainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="218*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!– Canvas in the main middle section –>
<Canvas x:Name="MainCanvas" Grid.Row="1">
<Image x:Name="MoveableImage" Width="55" Source="questionmark2.jpg"
Canvas.Left="0" Canvas.Top="0" />
</Canvas>
<!– Menu at the top –>
<Menu Grid.Row="0" Margin="3">
<MenuItem Header="Move It" Margin="5"
></MenuItem>
</Menu>
<ToolBar Grid.Row="2" >
<Button Content="Move It"
/>
</ToolBar>
<Button Grid.Row="1" VerticalAlignment="Bottom"
HorizontalAlignment="Right" Width="100"
Height="33" Content="Move It" Margin="0,0,4,2"
/>
</Grid>
</Window>
(If you've looked at the markup closely and think that the order of elements is haphazard, you would be wrong. Try moving the MenuItem to what seems a more logical position above the Canvas and you will get an Error when the code is completed. As you will see, the code behind for the MenuItem will eventually have a link to the Image. So therefore the Image must be created first in the top down XAML file, before the MenuItem can know about it . I often think that it's these little potential Gotchas that make the WinForms-to-WPF learning curve so difficult.)
This is what it should look like:

Creating the Command
Let's start by creating a new Command Class called MoveItCommand. It will have a single property named MoveIt, a backing field named _move it and a parameterless constructor. The property and field are of type RoutedUICommand, but apart from that are standard and really don't need any additional explanation:
Private Shared _moveit As RoutedUICommand
Public Shared ReadOnly Property MoveIt() As RoutedUICommand
Get
Return _moveit
End Get
End Property
The constructor is used to create the various keyboard and mouse gestures that can be used to move the image. For the purposes of demonstration, I've gone totally overboard on these and have included four variations in the final version. But for clarity, I am only showing one in the code snippet below:
Shared Sub New()
' Add keyboard and mouse gestures
Dim UserInputs As New InputGestureCollection()
UserInputs.Add(New KeyGesture(Key.M, ModifierKeys.Alt))
' Assign these gestures to the _moveit field (and thereby to the MoveIt property)
_moveit = New RoutedUICommand("Move Element", "Move", GetType(MoveItCommand), UserInputs)
End Sub
- The constructor begins by creating a new empty collection of mouse gestures.
- The second line creates and stores a gesture which takes the Alt and M keys as the combination to be used to fire this command. Notice the order of the keys used as arguments – effectively it is "M & Alt" which isn't the way we usually think of the combination. If you switch the order and place the Modifier key first, you will get a runtime error. Trust me, I've been there, done that!
- Finally, a new RoutedCommand is created, containing descriptive text, its name, owner type (which is this custom command class – MoveItCommand), and the collection of Gestures that will work with this command.
Note that all the members of this class are Shared, ensuring that only instance of the Command will be in use in the application when it runs.
Additional Gestures
If you are happy with how the Class and its Constructor works, I'll now add in those other gestures I mentioned. These include F12 on its own, a mouse click on its own and finally a combination of mouse click and key press. Here's the revised code:
Shared Sub New()
' Add keyboard and mouse gestures
Dim UserInputs As New InputGestureCollection()
UserInputs.Add(New KeyGesture(Key.M, ModifierKeys.Alt))
UserInputs.Add(New KeyGesture(Key.F12, ModifierKeys.None))
UserInputs.Add(New MouseGesture(MouseAction.RightClick, ModifierKeys.None))
UserInputs.Add(New MouseGesture(MouseAction.LeftClick, ModifierKeys.Shift))
' Assign these gestures to the _moveit field (and thereby to the MoveIt property)
_moveit = New RoutedUICommand("Move Element", "Move", GetType(MoveItCommand), UserInputs)
End Sub
- The first gesture is Alt and M, which I've already covered.
- The second gesture is the F12 key on its own. Note that you must include Modifiers.None. if you don't, you will get a runtime error.
- The third gesture will fire the command when the mouse is right clicked anywhere in the Window. Because of the way that WPF and RoutedCommands work, this effectively means that you can still click on the Image to make it move. If you wanted to limit the mouse click to the Image only, you could harness the power of Bubbling and Tunneling events to trap the mouse button press at the Image level. I haven't done that in this example.
- The final gesture takes a combination of both the mouse left button click together with holding down the Shift key. Quite awkward to use and only included to demonstrate the range of available gestures.
Command Bindings
Having created the custom Command Class, if we want to use it in the XAML – and we do – then it is necessary to create an XML namespace mapping. Without this link, the XAML markup would have no idea about the existence of the class and its property. The syntax is fairly simple:
xmlns:local="clr-namespace:GetValue"
The alias of 'local' is used as the key which is mapped to the namespace in which the MoveItCommand class resides. The namespace is the same as the name of the project and in this case the project is named 'GetValue'.

Given this namespace mapping, we can now set up the CommandBinding in the XAML pane:
<Window.CommandBindings>
<CommandBinding Command="local:MoveItCommand.MoveIt"
Executed="CommandBinding_Executed"
CanExecute="CommandBinding_CanExecute"/>
</Window.CommandBindings>
As you see from the snippet above, you create a new CommandBinding inside a CommandBindings collection. The Command property of the CommandBinding points to that MoveIt property created in the MoveItCommand class.
The Executed and CanExecute properties point to two methods which we will create next in the code-behind.
Executing The CommandBinding The task of the CommandBinding_Executed method is to carry out whatever tasks we want to have actioned when the command is invoked. In this demonstration project, this task is simply to shunt the image a few units to the right. So the code is as follows:
Private Sub CommandBinding_Executed(ByVal sender As System.Object, ByVal e As System.Windows.Input.ExecutedRoutedEventArgs)
' Move the image 5 units to the right
Dim LeftPos As Double = MoveableImage.GetValue(Canvas.LeftProperty)
MoveableImage.SetValue(Canvas.LeftProperty, LeftPos + 5)
End Sub
(If you are not sure about how the GetValue and SetValue functions work, you can read up on it in my blog here).
CanExecute
CanExecute is an optional feature which can be quite useful. In this demonstration, we will only allow the Command to work (and therefore only allow the Image to continue moving to the right) if it hasn't reached the right hand edge of the Canvas. More subtly, if CanExecute becomes set to False, any controls that are bound to the Command will automatically be disabled. I will add Command Bindings to the buttons, etc shortly.
First, here is the code for the CanExecute method:
Private Sub CommandBinding_CanExecute(ByVal sender As System.Object, ByVal e As System.Windows.Input.CanExecuteRoutedEventArgs)
' Only allow execution of the command if the image
' has not yet reached the right hand edge.
e.CanExecute = MoveableImage.GetValue(Canvas.LeftProperty) < (MainCanvas.ActualWidth – MoveableImage.Width)
End Sub
It tests the current position of the Image to see if it has reached the right hand edge of the Canvas. CanExecute will be set to True if there is still space to the right side of the Image, otherwise it will be set to False.
The complete code behind for the Window and the Custom Command class together now looks like this:
Partial Public Class Window3
Private Sub CommandBinding_Executed(ByVal sender As System.Object, ByVal e As System.Windows.Input.ExecutedRoutedEventArgs)
' Move the image 5 units to the right
Dim LeftPos As Double = MoveableImage.GetValue(Canvas.LeftProperty)
MoveableImage.SetValue(Canvas.LeftProperty, LeftPos + 5)
End Sub
Private Sub CommandBinding_CanExecute(ByVal sender As System.Object, ByVal e As System.Windows.Input.CanExecuteRoutedEventArgs)
' Only allow execution of the command if the image
' has not yet reached the right hand edge.
e.CanExecute = MoveableImage.GetValue(Canvas.LeftProperty) < (MainCanvas.ActualWidth – MoveableImage.Width)
End Sub
End Class
Public Class MoveItCommand
Private Shared _moveit As RoutedUICommand
Public Shared ReadOnly Property MoveIt() As RoutedUICommand
Get
Return _moveit
End Get
End Property
Shared Sub New()
' Add keyboard and mouse gestures
Dim UserInputs As New InputGestureCollection()
UserInputs.Add(New KeyGesture(Key.M, ModifierKeys.Alt))
UserInputs.Add(New KeyGesture(Key.F12, ModifierKeys.None))
UserInputs.Add(New MouseGesture(MouseAction.RightClick, ModifierKeys.None))
UserInputs.Add(New MouseGesture(MouseAction.LeftClick, ModifierKeys.Shift))
' Assign these gestures to the _moveit field (and thereby to the MoveIt property)
_moveit = New RoutedUICommand("Move Element", "Move", GetType(MoveItCommand), UserInputs)
End Sub
End Class
At this point, you can run the project and use any of those four gestures to move the Image. Once the Image hits the right hand edge, it will stop moving. The menu item, the two buttons don't play any part in the action yet – that is, clicking them will have no effect and they won't become disabled when the Image reaches the right hand limit.
Binding the Command to the Controls
All that remains to do is to bind this custom command to the menu item and the two buttons. Now things really do become simple and you can begin to see the potential benefit of using a Command. The following piece of markup is added to the MenuItem, the Button in the Toolbar and the Button in the Canvas:
Command="local:MoveItCommand.MoveIt"
With those bindings in place, you can move the Image by any of the seven methods included – the four input gestures and by clicking on any of the three controls. Note now that once the Image hits the right hand edge, those three controls all become disabled.

So, there is a fairly simple example of using your own Command. You can see the final version of the XAML markup here, and also the code behind here.











