将 WPF 快捷键绑定到 ViewModel 中的命令

Posted

技术标签:

【中文标题】将 WPF 快捷键绑定到 ViewModel 中的命令【英文标题】:Binding a WPF ShortCut Key to a Command in the ViewModel 【发布时间】:2011-01-23 21:14:39 【问题描述】:

我有一个使用 MVVM 模式的 WPF 应用程序。将按钮连接到 VM 非常简单,因为它们实现了 ICommand。我有一个类似的上下文菜单。下一步是为上下文菜单创建快捷键。我不知道如何让快捷键调用命令。这是一个例子:

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

现在我添加了这个:

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

尝试将快捷键连接到同一个绑定,但这不起作用。错误是:

错误 169 无法在“KeyBinding”类型的“Command”属性上设置“Binding”。 “绑定”只能在 DependencyObject 的 DependencyProperty 上设置。

没有办法将此事件与命令挂钩吗?我想不通。

提前致谢!

比尔

【问题讨论】:

我应该提到我也在使用 Josh Smith 的 RelayCommand。 【参考方案1】:

已经能够在 DataGrid 级别上添加键绑定。像这样:

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>

查看模型:

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 ;

【讨论】:

【参考方案2】:

我同意在 XAML 中执行此操作是理想的,但为了完整起见,您也可以在代码中添加绑定。如果您在构造函数中执行此操作,只需确保它在调用 InitializeComponent() 之后即可

InputBindings.Add(new KeyBinding(btnUpdate, new KeyGesture(Key.U, ModifierKeys.Control));

【讨论】:

+1 这个方法允许我把它放到我的视图中,因为我需要这个函数只使用 UI 元素。 但这会将按钮控件 btnUpdate 绑定到快捷键 Ctrl-U,而不是像 Michel Keijzers 的 XAML 那样绑定到命令。 我正在回答试图绑定到名为“btnUpdate”的东西的原始帖子。 这可行,但你必须用 yourButton.Command 替换 btnUpdate。【参考方案3】:

我写了一个custom markup extension 来“绑定”InputBindings 到命令,它几乎可以像真正的绑定一样使用:

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

请注意,此标记扩展使用私有反射,因此只有在您的应用程序完全信任运行时才能使用它...

另一个选择是使用CommandReference 类。它可以在可用的 MVVM 工具包here 中找到。这可能是一种更简洁的方法,但使用起来有点复杂。

注意在WPF 4中,InputBinding.CommandInputBinding.CommandParameterInputBinding.CommandTarget属性是依赖属性,所以可以正常绑定

【讨论】:

太棒了!这正是我一直在寻找的。谢谢!! 我关注了 WPF MVVM 文档中的 exs - 很好的例子!正是我想做的。不幸的是,上下文菜单项工作正常,但快捷键什么也不做。我什至无法调试它,因为当我按下快捷键时没有任何反应。 难道我想在 ContextMenu 而不是标准菜单上的快捷键上使用这些? 您使用了哪种技术?标记扩展或 CommandReference 类? CommandReference - 我在 XAML 中放置 KeyBinding 的位置似乎很重要。如果我把它放在窗口中的 DataGrid 中,我会在 CanExecute 中打断点 - 但它似乎总是返回 false。【参考方案4】:

以下代码可用于将快捷键直接绑定到命令:

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

在视图的 XAML 代码中的 Window.Resources 之后添加它。

【讨论】:

是的,不知道 OP 的问题是什么,但这很好用。 (我正在使用 MVVM 灯) 他特别说这不起作用,所选答案解释了原因:他没有使用 WPF4。不知道您为什么将他的确切代码发布为“答案” Modifiers Ctrl?【参考方案5】:

WPF Application Framework (WAF) 项目的 ShortcutKey 示例中显示了将 WPF 快捷键绑定到 ViewModel 的 Command 属性的另一种方法。

【讨论】:

谢谢...我需要一些时间来研究它(这意味着我现在没有太多时间,但我赞成,因为该链接似乎非常有用(不仅仅是因为我的问题)。 这个答案只是为了宣传,没有任何帮助,给定的链接也没有

以上是关于将 WPF 快捷键绑定到 ViewModel 中的命令的主要内容,如果未能解决你的问题,请参考以下文章

WPF MVVM:如何将 GridViewColumn 绑定到 ViewModel-Collection?

从 View 到 ViewModel 的 WPF 事件绑定?

将UserControl绑定到ViewModel(Caliburn Micro WPF)

如何将 WPF DataGrid DataColumns 可见性绑定到 UserControl 的 ViewModel 上的属性?

WPF 将窗口标题绑定到 ViewModel 属性

为啥我的组合框无法绑定到 ViewModel 中的 List<string>? WPF