Lester's WPF\SL Blog

Simple, Easy & Beautiful

New WPF Features: Key\Gesture Binding

New WPF Features: Key\Gesture Binding

Rate This
  • Comments 6

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.

 

 

Share this post

 

Attachment: WpfModelViewApplication3.zip
  • tht's nice. Simplfies code a lot. Thanks

  • I fail to understand how this would be an improvement.

    This means that the ViewModel decides which keys(+modifiers) are used to execute a command? This is imho the same as a ViewModel that has knowledge of the available menu controls in a View.

  • That's awesome! Thanks so much.

  • 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 binding

  • @llester I got it :)

    (Thanks for the series btw)

  • 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?

Page 1 of 1 (6 items)