New WPF Features: KeyGesture Binding
This is part of a series on New WPF Features
We got a lot of feedback to improve the way a developer could set binding to the input keys and modifiers. Earlier, the command property on the inputbinding class was not a Dependency property - so binding to it was out of question. Also it didnt inherit the datacontext of the parent. There are workarounds and most likely you would be doing something like the below as is done in the CoreMVVM libraries.
<Window.Resources>
<!-- Allows a KeyBinding to be associated with a command defined in the View Model -->
<c:CommandReference x:Key="ExitCommandReference" Command="{Binding ExitCommand}" />
</Window.Resources>
<Window.InputBindings>
<KeyBinding Key="X" Modifiers="Control" Command="{StaticResource ExitCommandReference}" />
</Window.InputBindings>
However, now we have baked this in the framework so the experience is a lot better. InputBindings inherits from Freezable for the DataContext and exposes the commands as Dependency Properties. Now the above looks something like
<Window.InputBindings>
<!-- See above for the previous experience -->
<KeyBinding Command="{Binding ExitCommand}" Key="X" Modifiers="Control"/>
</Window.InputBindings>
Aint that sweet.. You could also bind the Key and Modifiers as below.
<Window.InputBindings>
<!-- See above for the previous experience -->
<KeyBinding Command="{Binding ExitCommand}"
Key="{Binding ExitCommand.GestureKey}"
Modifiers="{Binding ExitCommand.GestureModifier}"/>
</Window.InputBindings>
So whats the plumbing needed for this..
In your delegateCommand class, declare the following 3 properties:
public Key GestureKey { get; set; }
public ModifierKeys GestureModifier { get; set; }
public MouseAction MouseGesture { get; set; }
Now in the ViewModel, set these properties when you initialize the command
public ICommand ExitCommand
{
get
{
if (exitCommand == null)
{
exitCommand = new DelegateCommand(Exit);
exitCommand.GestureKey = Key.X;
exitCommand.GestureModifier = ModifierKeys.Control;
exitCommand.MouseGesture = MouseAction.LeftDoubleClick;
}
return exitCommand;
}
}
Thats it... the sample code is attached.
Comments
Anonymous
October 29, 2009
tht's nice. Simplfies code a lot. ThanksAnonymous
October 29, 2009
The comment has been removedAnonymous
October 29, 2009
That's awesome! Thanks so much.Anonymous
October 29, 2009
Tim, you can also do something like <KeyBinding Command="{Binding ExitCommand}" Key="Y" Modifiers="Control" /> the main benefit here is that you no longer require comething like a commandreference class for command bindingAnonymous
October 30, 2009
@llester I got it :) (Thanks for the series btw)Anonymous
December 02, 2009
I'm trying this in VS 2010 Beta 2. I want to fire the bound command when a user double-clicks an item in a ListView. However the command only fires when the user double-clicks on an area of the ListView that contains no items. I've tried setting InputBindings on the individual ListViewItems using a style but it seems InputBindings cannot be set in a style. Any ideas?