How to Add Commands to Custom WPF Control

Back in Beta days of .NET Framework 3.0, I wrote a blog post about commands in WPF and how easy it is to add common commands to your WPF menus and create custom commands to use them.

On the other hand, so far I've written some posts about writing a custom WPF control:

But now and before writing a separate post to show a sample custom WPF control, I want to cover another topic about adding commands to custom WPF controls.

Adding a command to a custom control is so easy.  The main part is registering the command in static constructor of your custom control.  There are two kinds of commands that you can add to your custom controls:

Therefore I split my post into two parts and cover how to add each of these two kinds to your controls.

New Command Type

In this case you must register your command in static constructor of control.  This RoutedCommand is a static public member of class and you need to set it to a correct value.  In order to do this you can create a InputGestureCollection object in static constructor and add an input to this collection.  In my sample, I add a KeyGesture to inputs which yields that this command runs every time that user press Ctrl + M.  After adding an input to InputGestureCollection, you can assign a new instance of RoutedCommand object to your command.  This new object can be created by passing a string name, type of your custom control and your newly added InputGestureCollection object to its constructor.  After passing these steps your new command type is registered.

public class MyControl : ItemsControl

{

    public static RoutedCommand myCommand;

 

    static MyControl()

    {

        InputGestureCollection myInputs = new InputGestureCollection();

        myInputs.Add(new KeyGesture(Key.M, ModifierKeys.Control));

 

        myCommand = new RoutedCommand("CustomCommand",

            typeof(MyControl), myInputs);

    }

}

But story has not ended yet.  You still need to create a binding for your command to be able to use it.  This step is common with existing commands so I'll describe it in next section.

Existing Command

Whether you're defining a new command type or using an existing command, should declare a CommandBinding object for your command to bind it to its handler.  After declaring this CommandBinding object, you must register it using CommandManager.RegisterClassCommandBinding() method.  Note that your handler must be static.  In below code I bind existing Save command in WPF to my own CommandHandler handler to show a MessageBox whenever this command is running.

public class MyControl : ItemsControl

{

    static MyControl()

    {

        CommandBinding binding =

            new CommandBinding(ApplicationCommands.Save, CommandHandler);

        CommandManager.RegisterClassCommandBinding(typeof(MyControl), binding);

    }

 

    private static void CommandHandler(object target, ExecutedRoutedEventArgs e)

    {

        MessageBox.Show("Command Handled!");

    }

}

And finally in last example I modify the code from previous section to create a binding for my new command type.

public class MyControl : ItemsControl

{

    public static RoutedCommand myCommand;

 

    static MyControl()

    {

        InputGestureCollection myInputs = new InputGestureCollection();

        myInputs.Add(new KeyGesture(Key.M, ModifierKeys.Control));

 

        myCommand = new RoutedCommand("CustomCommand",

            typeof(MyControl), myInputs);

 

        CommandBinding binding = new CommandBinding();

        binding.Command = myCommand;

        binding.Executed += new ExecutedRoutedEventHandler(binding_Executed);

 

        CommandManager.RegisterClassCommandBinding(typeof(MyControl), binding);

    }

 

    private static void binding_Executed(object sender, ExecutedRoutedEventArgs e)

    {

        MessageBox.Show("Command Handled!");

    }

}

Now playing: Ricky Martin - Life

[advertisement] Axosoft OnTime 2008 is four developer tools in one: bug tracking, project wiki, feature management, and help desk. It manages your development process so developers can focus on coding. Installed or Hosted – Free Single-user license -- Free 30-day team trial.

9 Comments : 05.15.07

Feedbacks

 avatar
#1
DotNetKicks.com
05.15.2007 @ 11:13 AM
You've been kicked (a good thing) - Trackback from DotNetKicks.com
 avatar
#2
Matthieu MEZIL
05.15.2007 @ 2:57 PM
Your article is very interesting. Thanks. Matthieu
 avatar
#3
TrackBack
05.24.2007 @ 6:50 AM
Commands aren't necessarily the first thing you want to go deep on in WPF, however they are a wonderful feature that a number of people write about when they discover them.
 avatar
#4
Bob Doyle
11.18.2007 @ 6:50 PM
hey, i thgouht you were posting the src to this?
 avatar
#5
ivana
04.10.2008 @ 12:31 AM

Thanks for the article. Manage to add my command in the WPF Custom Control Gauge I downloaded from <a href="http://www.nextwavesoft.com">http://www.nextwavesoft.com</a>

Pingback from Exam 70-502 Microsoft .NET Framework 3.5 Windows Presentation Foundation Study Links - Part 2 | One .Net Way

 avatar
#7
Ali
03.10.2009 @ 1:35 AM

Thanks a lot Keyvan for this awesome post.

I have already created my own custom control and I've added a ApplicationCommand.New to it. I want this command be mannaged by the window which contains my custom control. I don't know how to pass it to the window. Now, I made the Executed event of the command in custom control internal to access it from the window. I know that it is wrong and it should be vice versa. Do you have any idea?

Regards,

Ali

 avatar
#8
Ali
03.10.2009 @ 4:16 AM

Hi again.

I should say that I found the solution by the help of your post. so ignore my previous post. The solution was creating an instance of the CommandBinding class in static constructor of the custom control with just command parameter. I mean:

CommandBinding binding = new CommandBinding(ApplicationCommands.New);

CommandManager.RegisterClassCommandBinding(typeof(MyCustomControl), binding);

Then when we bind the command in the container window both of the command, from custom control and from the container window will be executed in container window.

I updated my post to be available to others who might have the same issue.

I do appologize for this disturbance.

Thanks again.

 avatar
#9
Manoj
03.25.2009 @ 12:52 AM

Hi,

This article is very interesting. Is there any next post for this article that explains how to use this in XAML.

--

Thanks

Manoj

Leave a Comment