Introduction
Commanding in WPF is unlike your traditional events in WinForms. Commands were primarily designed to be used at the application level, but they have become one of the most popular features among developers when it comes to UI programming (we tend to use them more than they should be). Commands enable the developer to define a task once and “attach” it multiple times without having to go through the traditional means which would require duplicating the code or even calling it in more than one place. (This is the magic.) WPF intrinsically provides five commands that you can use out of the box.
ApplicationCommands
ComponentCommands
EditingCommands
MediaCommands
vNavigationCommands
I have explored them and have taken a liking to ApplicationCommands
. (In fact this is the one that most developers will use.)
To use the command, do the following:
- Link your custom/predefined command to a control that you want to respond to the command and add an input gesture to the command.
- Create a handler for the command and use the
CommandBindings
class to bind the handler to the control.
- Add the binding to the control’s Commands collection.
So let’s delve into some code to demonstrate WPF commanding.
Let's first look at the XAML:
<Window x:Class="Commanding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="340" Width="509"
xmlns:MyCommands="clr-namespace:Commanding">
<Grid>
<Border Padding="5" BorderBrush="Black"
BorderThickness="2" CornerRadius="5" Margin="10">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center"
VerticalAlignment="Top" Height="64">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center"
VerticalAlignment="Center">
<Label>Type Your Name :</Label>
<TextBox Name="txtName" Width="200"></TextBox>
<Button Command="MyCommands:Commands.HelloCommand"
Content="Say Hello" Padding="3"></Button>
</StackPanel>
<CheckBox Name="chkCanExecute"
Content="Uncheck to suppress command execution" IsChecked="True"/>
</StackPanel>
</Border>
</Grid>
</Window>
The key section in the XAML code is the namespace called MyCommands
and the Button
element. The namespace...
xmlns:MyCommands="clr-namespace:Commanding
... references the namespace in which the custom command is defined.
The Button
element’s Command
property is associated with the custom command:
<Button Command="MyCommands: CustomCommand.HelloCommand"
Content="Say Hello" Padding="3"></Button>
Below you will see the HelloCommand
property from the CustomCommand
class.
namespace Commanding
{
public class CustomCommand
{
private static System.Windows.Input.RoutedUICommand helloCommand;
static CustomCommand ()
{
System.Windows.Input.InputGestureCollection gestureCollection
= new System.Windows.Input.InputGestureCollection();
gestureCollection.Add(new System.Windows.Input.KeyGesture
(System.Windows.Input.Key.H, System.Windows.Input.ModifierKeys.Control));
helloCommand = new System.Windows.Input.RoutedUICommand
("HelloCommand", "HelloCommand", typeof(Commands), gestureCollection);
}
public static System.Windows.Input.RoutedUICommand HelloCommand
{
get { return helloCommand; }
}
}
}
Below I bind the property from the custom command, then assign a handler and add it to the Window’s CommandBindings
. Notice that I didn't bind it to the button control directly.
namespace Commanding
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
CommandBinding binding = new CommandBinding();
binding.Command = Commanding.Commands.HelloCommand;
binding.Executed += new ExecutedRoutedEventHandler(binding_Executed);
binding.CanExecute += new CanExecuteRoutedEventHandler(binding_CanExecute);
this.CommandBindings.Add(binding);
}
void binding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = (bool)chkCanExecute.IsChecked;
}
void binding_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show(string.Format("Hello {0}, you have mastered commanding", txtName.Text));
}
}
}
Notice the binding_CanExecute
method. This gives you conditional execution. When you subscribe to this event, this method is called first to see if it is ok to call your command. We use a check box to turn this on and off.
In the next post, we will look at commanding and MVVM (Model View ViewModel). Here, you will see the power of commanding. The code that is in the Window1
class violates a lot of GUI principles. With MVVM, you will have a centralized place (to the ViewModel) where you can have reusable commands.
For more simple code, go to www.olivercode.net.
History
- 14th May, 2009: Initial post