views:

942

answers:

3

Hi,

I have a WPF app that is using the MVVM pattern. Hooking up buttons to the VM is pretty straight forward since they implement the ICommand. I have a context menu that works similar. The next step is to create shortcut keys for the context menu. I can't figure out how to get the shortcut key invoke the Command. Here is an example:

        <MenuItem Header="Update" Command="{Binding btnUpdate}" >
            <MenuItem.Icon>
                <Image Source="/Images/Update.png"
           Width="16"
           Height="16" />
            </MenuItem.Icon>
        </MenuItem>

now I've added this:

<Window.InputBindings>
    <KeyBinding Key="U"
          Modifiers="Control" 
          Command="{Binding btnUpdate}" />
</Window.InputBindings>

to try and connect the shortcut keys to the same binding, but this doesn't work. The error is

"Error 169 A 'Binding' cannot be set on the 'Command' property of type 'KeyBinding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject."

Isn't there a way to hook up this event to the Command? I can't figure this out.

thanks in advance!

Bill

+3  A: 

I wrote a custom markup extension to "bind" InputBindings to commands, which can be used almost like a real binding :

<UserControl.InputBindings>
    <KeyBinding Modifiers="Control" Key="E" Command="{input:CommandBinding EditCommand}"/>
</UserControl.InputBindings>

Note that this markup extension uses private reflection, so it can only be used if your application runs in full trust...

Another option is to use the CommandReference class. It can be found in the MVVM toolkit available here. It's probably a cleaner approach, but a bit more complex to use.

Note that in WPF 4, the InputBinding.Command, InputBinding.CommandParameter and InputBinding.CommandTarget properties are dependency properties, so they can be bound normally

Thomas Levesque
Excellent! This is just what I was looking for. Thank You!!
Bill Campbell
I followed the exs in the WPF MVVM Docs - great examples! Exactly what I want to do. Unfortunately, the context menu items work fine, but the shortcut keys do nothing. I can't even figure out to debug this since nothing happens when I press the shortcut keys.
Bill Campbell
Could it be that I am trying to use these on shortcut keys on a ContextMenu instead of a standard menu?
Bill Campbell
which technique did you use ? the markup extension or the CommandReference class ?
Thomas Levesque
The CommandReference - it does seem to matter where in the XAML I put the KeyBinding. If I put it in the DataGrid that is in the window I do hit the breakpoint in the CanExecute - but it seems to always return false.
Bill Campbell
I was thinking that if I put the KeyBinding anywhere in the window that it would work but that doesn't seem to be the case.
Bill Campbell
the KeyBinding is triggered when the control on which it's defined is focused... perhaps that's why it doesn't work for you ?
Thomas Levesque
That's possible. I would have thought that if the KeyBinding was put on the window which has the controls on it, that it would be triggered by the child controls as well, but maybe not?
Bill Campbell
Finally got it to work. It was just getting the KeyBindings and CommandReferences in the right places. Not just inside the window but inside the first grid.
Bill Campbell
A: 

An alternative approach for binding a WPF Shortcut Key to a Command property of the ViewModel is shown in the ShortcutKey sample of the WPF Application Framework (WAF) project.

jbe
+1  A: 

I agree that doing it in XAML is ideal, but for completeness sake, you could also add your binding in code. If you do it in the constructor, just make sure it is after the call to InitializeComponent()

InputBindings.Add(new Keybinding(btnUpdate, new KeyGesture(Key.U, ModifierKeys.Control));
Eddie Deyo