Alvaro Dias

Going the InputBindings way: Part 1 - Keyboard Accessibility

You can specify an input binding in XAML as shown below.

  <Window.InputBindings>
    <KeyBinding
      Gesture="CTRL+A"
      Command="{Binding KeyPressedCommand}" />
  </Window.InputBindings>

Now, when you do this, you also need to make sure that the DataContext of the Window is assigned correctly.
i.e. the instance that is assigned to the DataContext has a property called KeyPressedCommand which implements the ICommand interface.

The same can be done in code by writing a few lines of code.

var keyBinding = new KeyBinding(this.KeyPressedCommand, Key.A, ModifierKeys.Control);
this.InputBindings.Add(keyBinding);

In both the cases XAML and code-behind – When you do the CTRL+A key gesture, the KeyPressedCommand.Execute method will get called.

It is recommended that you specify a key gesture including one key and one modifier key. In fact, if you change the third parameter in the above code to ModifierKeys.None, you will get a NotSupportedException. The way I see it, it has both pros and cons. On one hand, it prevents me from registering a binding for just a single modifier-less key press. Which would make me look for workarounds. On the other hand, it could potentially help prevent poor designs and a bad user experience. e.g. consider a case where you add the above binding sans the modifier – now all of a sudden you cannot input a into the textbox. Instead KeyPressedCommand gets executed.

The same limitation however, does not exist when you specify the binding in XAML. Instead of specifying the Gesture you could instead specify Key="A" and it would work just fine. While working with XAML there are other caveats we need to worry about though.

As you know you can specify bindings using Gesture="CTRL+A" or by specifying Modifiers="Control" and Key="A". Now, if you mix and match these parameters, the behaviour is unpredictable. For example, the below code actually responds to CTRL+B.

  <Window.InputBindings>
    <KeyBinding
      Gesture="CTRL+A"
      Key="B"
      Command="{Binding KeyPressedCommand}" />
  </Window.InputBindings>

While using KeyBindings, there are two properties that prove to be very useful.

  1. CommandTarget – This property is useful when the Command property is bound to an instance of a RoutedCommand. In this case the CommandTarget specifies the instance whose CanExecute and Executed events are raised. If this property is not set, then the element that currently has keyboard focus is used as the CommandTarget
  2. CommandParameter – this property specifies any parameter that you would like to pass to the command. This means that any data that you would like to pass on that is necessary for executing the command can be passed here.

Hope the above information was helpful.

You can find more information on the above topic at the following places