WPF Commands Part 2: Command Bindings and Gestures


Welcome to Part 2 of WPF Commands. If you have not looked at my previous entry talking about the basics, you should have a look at it here. That should set you up for understanding this example.

What are Command Bindings? Simply put it, it allows us to specify the commands that a particular control will be listening to, and the event handlers that will implement the command logic. If you remember that all commands in WPF implement ICommand interface, it defines two methods CanExecute and Execute. Controls (ones that can handle input focus) typically understand how to execute commands on themselves. So now, how do we “make” a control understand a different command?

For example, I want to be able to make a TabContainer change tabs on a button click. How do we achieve that? No brainer here, with Command Bindings. To make it more exciting, WPF also allows us to hook up commands with Input Gestures. It’s an abstract class, and we will be dealing with two types of gestures, namely KeyGesture and MouseGesture. Examples of mouse gestures are left button click, scroll wheel click and key gestures speak for themselves. Both kinds of gestures allow us to also define an optional control modifier, e.g. Control + Left Button Click, or Shift + C key. A Command Binding allows us to wire up a control to a custom Command, or WPF’s library of Commands, or Input Gestures.

The sample application will be the same as my previous post, but we will be using the Buttons and key gestures to navigate between the tabs on the Tab Container. Please take a look at this video of this demo.

wpfcommand12

Here’s a snipplet of Xaml for the CommandBindings.

<window .CommandBindings>
        <commandbinding Command="NavigationCommands.PreviousPage"
                CanExecute="CanPreviousPageCommandExecute" Executed="OnPreviousPageCommandExecute" />
        <commandbinding Command="NavigationCommands.NextPage"
                CanExecute="CanNextPageCommandExecute" Executed="OnNextPageCommandExecute" />
</window>

The CommandBindings are hooked onto the Window’s CommandBindings. CommandBindings are a common property of many WPF Controls, so you can hook them up to any commands, custom or existing ones. In this case, we hooked it up to NavigationCommands.PreviousPage and NextPage, and specified the event handling methods that will contain the logic. What’s so great with this design is that it allows us to hook up any kind of command logic to virtually any commands and to any UI Controls. If you have used the Command Pattern before, you will remember that typically the command object will require a reference to the “receiver”, and command’s execute method will invoke the receiver’s behaviour. We are encapsulating the behavior of the receiver within the command and this allows us to invoke it’s behaviour when required.

WPF’s Routed Command’s implementation is different though. The main purpose still holds, which is to encapsulate the invocation of an object’s behaviour, as we have seen in my previous post where a TextBox internally knows how to execute a Copy or Paste command. The difference is WPF incoorporates this with the use of Command Bindings. I’d like to see Routed Commands as nothing but “named containers” that are routed from a source, via the visual tree, looking for an appropriate target. Command Bindings are “listeners” that waits for the right command to reach itself, and trigger the CanExecute and Execute logic we specify. Instead of the Command having a reference to it’s receiver and invoking it’s behvaiour, the command finds a Command Binding and executes it’s delegates, CanExecute and Execute. If you understand this so far, you can see that this is very flexible and powerful, and we can achieve great things. Many interesting implementations come to mind, first one being wiring up domain models/objects to Custom Commands, with delegate methods for Adding, Updating, Creating and Removing itself….hmm…..and I digress :)

Back to the subject at hand, let’s have a look at Key Gestures in Xaml.

<window .InputBindings>
    <keybinding Key="Left" Modifiers="Control" Command="NavigationCommands.PreviousPage" />
    <keybinding Key="Right" Modifiers="Control" Command="NavigationCommands.NextPage" />
</window>

Simple. Now we have hooked up the commands to Control modifier and Left/Right arrow keys. Let’s look at the hooking up of the Next/Previous Tab Butons.

Finally, the code behind for the CanExecute and Execute methods.

private bool CanNavigateToNextTab
{
    get
    {
        if (tabControl != null)
        {
            return tabControl.SelectedIndex < tabControl.Items.Count - 1;
        }
        return false;
    }
}

private bool CanNavigateToPreviousTab
{
    get
    {
        if (tabControl != null)
        {
            return tabControl.SelectedIndex != 0;
        }
        return false;
    }
}

private void OnNextPageCommandExecute(object sender, ExecutedRoutedEventArgs e)
{
    if (CanNavigateToNextTab)
    {
        tabControl.SelectedIndex += 1;
        e.Handled = true;
    }
}

private void OnPreviousPageCommandExecute(object sender, ExecutedRoutedEventArgs e)
{
    if (CanNavigateToPreviousTab)
    {
        tabControl.SelectedIndex -= 1;
        e.Handled = true;
    }
}

private void CanNextPageCommandExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = CanNavigateToNextTab;
    e.Handled = true;
}

private void CanPreviousPageCommandExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = CanNavigateToPreviousTab;
    e.Handled = true;
}

As mentioned in my previous post, the CanExecute returns a boolean and informs the source control (the button in this case), if the command can be executed and therefore enabling or disabling itself. The Execute methods simply increases or decreases the SelectedIndex by 1. Something that is useful to know is that, for these methods, the sender object will be the Window. This is because we have hooked up the CommandBindings to the Window for this example. The sender will always be the object that “accepts” the command. If you’re wondering why I did not place my CommandBindings on the TabContainer instead, it’s because I want the Window to handle the Key Gestures as well at the Window level, not the TabContainer level.

To sum it up, you have seen the ease of wiring up your command to a CommandBinding and key gestures. You could have used Mouse Gestures as easily too. WPF provides a great command system and I have yet to find any major flaws. Next post, I will discuss writing your own custom command with use of Command Target and Command Parameters.

You can download this VS2008 solution here. (if you have downloaded the one for WPF Commands Part 1, you don’t need to download this. They are the same :) )

Share this post :
About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 97 other followers

%d bloggers like this: