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

发布于 2024-08-24 11:04:23 字数 844 浏览 6 评论 0原文

我有一个使用 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 上设置。

没有办法将此事件连接到命令吗?我无法弄清楚这一点。

提前致谢!

账单

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

国产ˉ祖宗 2024-08-31 11:04:23

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

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

将此代码添加到视图的 XAML 代码中的 Window.Resources 之后。

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.

那片花海 2024-08-31 11:04:23

我编写了一个 自定义标记扩展 将 InputBindings “绑定”到命令,几乎可以像真正的绑定一样使用:

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

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

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

请注意,在 WPF 4 中,InputBinding.CommandInputBinding.CommandParameterInputBinding.CommandTarget 属性是依赖属性,因此可以正常绑定它们

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

一梦浮鱼 2024-08-31 11:04:23

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

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

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));
放血 2024-08-31 11:04:23

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.

锦上情书 2024-08-31 11:04:23

已经能够在 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 ;
}

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 ;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文