Click here to Skip to main content
15,881,600 members
Articles / Desktop Programming / WPF
Article

WPF Commands

Rate me:
Please Sign up or sign in to vote.
4.10/5 (26 votes)
19 Dec 2007CPOL5 min read 133.9K   3.1K   93   11
Overview of WPF commands and how to use them to improve your WPF code

Introduction

WPF commands are a really nice way by which one can re-use functionality of an application. In the demo project that is supplied with this article, I have built an example of a project that uses the WPF Commands Pattern in order to be able to sort customers. The application has different controls that invoke the same functionality and for this reason, the WPF Command Pattern fits perfectly. WPF commands can also be used for other scenarios where you want to disable a control if the input is incorrect as we will see further on in the article with the CanExecute.

Creating a Command

To use the WPF commands, you have to declare the command that you are going to use with a static declaration. When you declare the command, you can also specify "Input Gestures" that can invoke the command. You can think of input gestures as shortcuts. These are basically a key or even a combination of keys. In the demo project, for example, I use the F3 key as input gesture.

Screenshot - First.jpg

In the demo project, I created the command in the same class as my user interface window(CommandDemo.cs). In a real life project, I would suggest that the command is declared somewhere more central so that other Windows/Components can use the same command declaration. For example, if in the project I had another window that can sort customers, I would have created a class that has the command inside. By doing this, the command would be accessibly from the other window as well. You can think of commands as being similar to events. Someone executes the command and someone handles the command. The way I picture this in my head is…

"There are 3 guys Jon, Mark and Patrick that work in a store. The manager of the store decides that Patrick should wash the floor. Jon says “Wash Floor” and Patrick does it. Mark says “Wash Floor” and Patrick does it. So basically Patrick is the Command Handler and Jon, Mark are executing the command causing Patrick (the command handler) to do the operation. The manager that said that Patrick should wash the floor is the Command Binding."

This is a very basic explanation of how this pattern works. Maybe even a more confusing one. By the way, I was going to forget.... The RoutedCommand in WPF is similar to RoutedEvents. The caller raises (executes) the command and the command routes up in the WPF Visual Tree until a CommandBinding handles the command. You can stop the route by setting the e.Handled = true in the command handler.

Now let us continue on. So after defining the command, what you have to do is create the command binding. Basically, this implies that you need to specify who is going to do the operation. You do this by creating the following:

Screenshot - second.jpg

So what is left for us to do is to create the Mark and Jon that are actually executing the command. Some controls like the button have a command property where you can specify what command to use when the button is clicked (you can even pass a parameter to the command by using the CommandParameter property).

C#
>Command="local:CommandsDemo.SortCustomers" 

You can even execute the command manually from C# by using the following code:

C#
ICommand command = SortCustomers;
command.Execute("Name");

Part 2 - CanExecute

The WPF command has another cool feature, the CanExecute. Basically this is a way in which you can check if the command can execute or not. This is a very handy feature if you have a command that can only be executed under certain conditions. For example, you have a list of users in a ListBox >> You want to be able to delete a user >> You define a command that as a parameter takes the user id >> You determine which user to delete by getting the selected item of a ListBox and passing that id as the command parameter >> You want the command to execute only if a user is selected.

Screenshot - third.jpg

All controls that support the Command Pattern (such as the Button) handle the result of the CanExecute by disabling the control if CanExecute is false. If the control which invokes the command does not support the Command Pattern, don't worry because a command will only execute if the CanExecute is true. Yet there can be cases where you want to do an action if the command cannot be executed (for example, change the visibility of the control or change the text of the control). You can do this be handling the CanExecuteChanged event of the command. In the event handler of the CanExecuteChanged you have to call the CanExecute method of the ICommand in order to check what the current state of the command is.

C#
bool canExecute = command.CanExecute(paramterForCommand);

I created a helper method that accepts an ICommandSource and gives back the CanExecute state of the command.

C#
public static bool CanExecuteCommandSource(ICommandSource commandSource)
{
    ICommand baseCommand = commandSource.Command;
    if (baseCommand == null)
        return false;
    
    object commandParameter = commandSource.CommandParameter;
    IInputElement commandTarget = commandSource.CommandTarget;
    RoutedCommand command = baseCommand as RoutedCommand;
    if (command == null)
        return baseCommand.CanExecute(commandParameter);
    if (commandTarget == null)
        commandTarget = commandSource as IInputElement;
    return command.CanExecute(commandParameter, commandTarget);
}

You can use this method to verify the state of the command as shown in the demo. Ok.... I think that's it for now… I hope that this post gives you a better understanding of how commands work and how you can use them to make your application code better. Feel free to download the demo project that I have created for this post in order for you to visualize better how you can use the Command Pattern of WPF.

History

  • 19th December, 2007: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Other Uniblue Systems (www.uniblue.com)
Malta Malta
Check out my Blog
http://marlongrech.wordpress.com/

Currently building a WPF Controls library aka AvalonControlsLibrary
http://marlongrech.wordpress.com/avalon-controls-library/

Comments and Discussions

 
GeneralMy vote of 4 Pin
Dr. Hurol Aslan28-Nov-12 0:02
Dr. Hurol Aslan28-Nov-12 0:02 
GeneralMy vote of 3 Pin
Andy Missico18-Apr-12 20:04
Andy Missico18-Apr-12 20:04 
GeneralMy vote of 3 Pin
grizzlyb14-Jan-11 9:21
grizzlyb14-Jan-11 9:21 
GeneralMy vote of 3 Pin
initialcoder24-Aug-10 22:47
initialcoder24-Aug-10 22:47 
GeneralMy vote of 1 Pin
Dev_Smi3-Jun-10 20:36
Dev_Smi3-Jun-10 20:36 
GeneralDeleteCustomer.CanExecuteChanged - never called Pin
Hunsoul14-Nov-08 4:26
Hunsoul14-Nov-08 4:26 
GeneralNice example! :) Pin
FreeRider16-May-08 21:27
FreeRider16-May-08 21:27 
GeneralCalling AvalonCommandsHelper.CanExecuteCommandSource() in DeleteCustomer.CanExecuteChanged. Pin
redjackwong27-Jan-08 17:59
redjackwong27-Jan-08 17:59 
GeneralRe: Calling AvalonCommandsHelper.CanExecuteCommandSource() in DeleteCustomer.CanExecuteChanged. Pin
marlongrech27-Jan-08 22:50
marlongrech27-Jan-08 22:50 
GeneralRe: Calling AvalonCommandsHelper.CanExecuteCommandSource() in DeleteCustomer.CanExecuteChanged. Pin
redjackwong28-Jan-08 14:37
redjackwong28-Jan-08 14:37 
GeneralRe: Calling AvalonCommandsHelper.CanExecuteCommandSource() in DeleteCustomer.CanExecuteChanged. Pin
marlongrech28-Jan-08 21:26
marlongrech28-Jan-08 21:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.