Binding a WPF ShortCut Key to a Command in the ViewModel

浪子不回头ぞ 提交于 2019-11-26 13:44:07

问题


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


回答1:


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




回答2:


The following code can be used to bind a shortcut key directly to a command:

<Window.InputBindings>
    <KeyBinding Command="{Binding Path=NameOfYourCommand}" 
                Key="O" 
                Modifiers="Control"/>
</Window.InputBindings>

Add this after Window.Resources in the XAML code of your view.




回答3:


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));



回答4:


Have been able to add Keybinding on the DataGrid level. Like this :

Xaml :

<DataGrid 
                    AutoGenerateColumns="False"
                    ItemsSource="{Binding YourCollection}"                         
                    CanUserAddRows="False"                        
                    HeadersVisibility="Column" 
                    CanUserDeleteRows="False" 
                    CanUserSortColumns="True"
                    CanUserResizeRows="False"
                    CanUserResizeColumns="False"                       
                    SelectedItem="{Binding YourSelectedItem}" 
                    SelectionMode="Single" 
                    SelectionUnit="FullRow"
                   >
                <DataGrid.ContextMenu>
                    <ContextMenu>
                       **<MenuItem Header="Delete" InputGestureText="Del" Command="{Binding DeleteCommand}">**
                        </MenuItem>
                    </ContextMenu>
                </DataGrid.ContextMenu>
                **<DataGrid.InputBindings>
                    <KeyBinding Key="Delete" Command="{Binding DeleteCommand}" CommandParameter="Delete"/>**
                </DataGrid.InputBindings>
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Column Header" Binding="{Binding YourColumn}" IsReadOnly="True" />
                </DataGrid.Columns>
</DataGrid>

View Model :

public ICommand DeleteCommand
            {
                get
                {
                    return new DelegateCommand(ExecuteCommand, CanExecute);
                }
            }

  private void ExecuteCommand()
{
// your code to delete here.
   YourCollection.Remove(YourSelectedItem);
}

private void CanExecute()
{
// logic to check if the delete command can execute.
   return YourSelectedItem != null ;
}



回答5:


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.



来源:https://stackoverflow.com/questions/2382916/binding-a-wpf-shortcut-key-to-a-command-in-the-viewmodel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!