So a few weeks ago, we posted a tutorial on using the built in commands in WPF. Well, today we are going to take a look at the other side of that - creating and using your own custom command and command bindings. First we will take a look at setting up our own bindings to existing commands, and then we will see how to create our own commands from scratch.
So an important thing to know, in order for command binding to make sense, is that (like many things in WPF) commands bubble. So when a command is triggered, it bubbles up along the WPF element tree from its origin (the command target, which we talked about in the previous tutorial), looking for an element that recognizes and can handle the command. The way that you can set up an element to handle a command is by creating a command binding. This can be done in either XAML or the code behind code - and we are going to take a look at the XAML first.
<Window x:Class="CustomCommandTest.CommandWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Custom Command Test" Height="300" Width="300">
<Window.CommandBindings>
<CommandBinding Command="Help"
CanExecute="HelpCanExecute"
Executed="HelpExecuted" />
</Window.CommandBindings>
<Button Command="Help" Content="Help Command Button" />
</Window>
So here we have a pretty sad little window (all it has is a single
button). That button, when pressed, will cause the built in Help
command to be executed. Now, without any command bindings, that command
would just bubble up till it couldn't bubble up anymore, and just
disappear. But in this case, we added a command binding to the window.
This command binding listens for the Help command, and uses the
HelpCanExecute method to determine if the command can execute, and the
HelpExecute method to actually do the execution. These two methods
exist in the code behind for the window and look like this:
private void HelpCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
e.Handled = true;
}
private void HelpExecuted(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Hey, I'm some help.");
e.Handled = true;
}
The HelpCanExecute method is used to determine if the Help command
is enabled or disabled. Here, we have it enabled, by setting the
CanExecute property on the CanExecuteRoutedEventArgs to true. If
we had disabled it, anything linked to this command (like that button)
would automatically become disabled. The second line in that method sets
the Handled property on the event args to true - this lets the system
know that this command binding has handled this command, and that it
doesn't need to bubble farther up the UI element chain.
The HelpExecuted is what actually gets run when the command is
executed, and in this case all we do is show a message box. And of
course, we set the handled flag to true. Now, it is true that setting
handled to true is not needed here or in the HelpCanExecute (because
there are no other command bindings in this application, and there are
no other elements to bubble up to), but it is probably good practice.
Another interesting thing you can do with commands is hook input gestures up to them. Take a look at the following XAML:
<Window x:Class="CustomCommandTest.CommandWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Custom Command Test" Height="300" Width="300">
<Window.CommandBindings>
<CommandBinding Command="Help"
CanExecute="HelpCanExecute"
Executed="HelpExecuted" />
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Command="Help" Key="H" Modifiers="Ctrl"/>
<MouseBinding Command="Help" MouseAction="LeftDoubleClick" />
</Window.InputBindings>
<Button Command="Help" Content="Help Command Button" />
</Window>
With this XAML, we have added some imput gestures that will also trigger
the command. Now, if the window has focus, and you hit Ctrl+H or double
click anywhere, the help command get executed. This makes it really easy
to hook up common keyboard shortcuts. Need ctrl+s to save? You just have
to hook up a KeyBinding to call the right command.
Ok, now onto creating your own custom commands. There really isn't that much to it, so while we are at it, let's take a look at how to hook up things like command bindings and input gestures in code:
<Window x:Class="CustomCommandTest.CommandWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Custom Command Test" Height="300" Width="300">
<Window.CommandBindings>
<CommandBinding Command="Help"
CanExecute="HelpCanExecute"
Executed="HelpExecuted" />
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Command="Help" Key="H" Modifiers="Ctrl"/>
<MouseBinding Command="Help" MouseAction="LeftDoubleClick" />
</Window.InputBindings>
<StackPanel>
<Button Command="Help" Content="Help Command Button" />
<Button Content="My Command" x:Name="MyCommandButton" />
</StackPanel>
</Window>
public partial class CommandWindow : Window
{
public static RoutedCommand MyCommand = new RoutedCommand();
private bool _helpCanExecute = true;
public CommandWindow()
{
InitializeComponent();
CommandBinding cb = new CommandBinding(MyCommand,
MyCommandExecute, MyCommandCanExecute);
this.CommandBindings.Add(cb);
MyCommandButton.Command = MyCommand;
KeyGesture kg = new KeyGesture(Key.M, ModifierKeys.Control);
InputBinding ib = new InputBinding(MyCommand, kg);
this.InputBindings.Add(ib);
}
private void HelpCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = _helpCanExecute;
e.Handled = true;
}
private void HelpExecuted(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Hey, I'm some help.");
}
private void MyCommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void MyCommandExecute(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("My Command!");
_helpCanExecute = !_helpCanExecute;
}
Ok, so we have a bunch of new stuff here. The XAML is almost identical
(the only new thing is the addition of a new button, and surrounding the
two buttons with a StackPanel). So I think we can skip right to the
top of the C# code - the RoutedCommand. This is how you create a new
command - you create a new static RoutedCommand. Thats it. There
really is nothing else to it, since it is just sort of a connector piece
- the real meat is whatever you put in the execute and can execute
methods of the binding.
Now to bind that command to the window. Since we already know how to do
it in XAML, we did it in code here. You have to create a new
CommandBinding instance, which takes the command and the execute/can
execute methods. Once you have that, you just add it to the
CommandBindings collection on whatever UI element you want the binding
to be on - in this case, the window. And your all set!
Ah, but we still need something to actually trigger the command, and
this is where we use that new extra button in XAML named
MyCommandButton. This time we are setting the command property of the
button in C# code, and as you can tell, it is just as easy as it was in
XAML. All we do is set it to MyCommand and now when that button is
pressed, the MyCommandExecute method will get run.
Adding input gestures in code is just as easy. First, you create a
Gesture - and in our case we made a KeyGesture for the gesture Ctrl+M.
Then you take that gesture and make a new InputBinding - and the input
binding also takes the command you are binding to. Finally, you add that
new input binding to the InputBindings collection on whatever element
you want (in this case the window again).
Just as a random note, when you no longer want the binding to be active,
all you have to do is remove it from the collection that you added it to
(which is really easy since both the InputBindings and
CommandBindings have your standard collection manipulation methods.
Oh, and there is one last fun thing in the code above. As you probably
noticed, the execution of MyCommand will actually change the Can
Execute state of the Help command that we put together earlier. So as
you click on the MyCommandButton, the help button will toggle between
enabled and disabled states, as the _helpCanExecute variable changes.
I hope you enjoyed this intro to the fun world of WPF commands. While these examples here are kind of silly, this disassociation of the executor and the actual execution logic come in quite handy as programs get larger, especially once you take into account what can be done with bubbling commands.
Great article, it's just what i was looking for, an easy way to create a custom command. Thanks
So how would a user control handle this? In nother words how would you set up a command and have it executer in the window that has this user control
Thanks
Very helpful - much more so than some other 'tutorials' on the web.
Regards
exactly what i was looking for. great stuff. thanks.
There's a lot of stuff happening in the codebehind... is there no way to bind a command without touching the codebehind?
Like I have a command class somewhere and just bind it to the button (e.g. "Click here and an instance of the class is created and the appropriate methods are called").
If I have something like a Application.Copy command, then how do I change the command target's Text property?
Good example! I got a little confused looking at the mixed Help pre-defined command and the MyCommand custom command.
A brilliant article! After reading this article, I suddenly understood what it's all about:)
Nice Article Men.....It really help improved my Command concept.
Very Helpful.Thank you
very very good tutorial.
Thanks. Keep it coming.
Excellent tutorial, Really helped in understanding custom commands
awesome work!!! :)
Hi, I have a problem here.
My Scenario Is: 1. CustomControl: Having a Button buttonEnable 2. MainWindow: Uses the above CustomControl and main window will have the ExecutedProcedure. My problem is i wanted to add a customcommand to the button at run time and command should be executed at mainwindow(if i implement this execution procedure in customcontrol its working fine). Could you please tell me how to proceed to solve this problem.
Regards, Raj
Finally the good God has shown mercy.
I have been searching for a very very very simple WPF Command binding program and failed to find one. Every other example I saw was talking about everything except simplicity and dont know what hasnt been included in them such as Relay, Action, DelegateCommand, etc etc.
Thank you very much for the very simple example with the very detailed explanation. This is what every developer desires when trying to learn something new. Thanks to you, I can build any complex logic from now on using the start :)
I don't know what all this was about... tried it... didn't work.
My problem: I have a Window (MainWindow.xaml) with a UserControl (SurveyHeader.xaml) in it and inside that UserControl is another UserControl (GetSurveyByID.xaml). I have a private void in MainWindow.xaml that i want to run when a button (btnGetSurvey) is clicked in GetSurveyByID.xaml.
This one line solution worked quite well for me.
great! Of I need to acces from execute, the datacontext of the window? (data class or dataview )?
Thank for your article. \^\^
Mel
Nice
Thank you very much for this tutorial! It is so helpful for me :) Nice job!
Very nice.
It has very helpfull to me.
Cheers...
Really such a nice article..Keep it up buddy..
Raja Moparthi