键绑定一个RelayCommand

Joe*_*ite 27 wpf key-bindings mvvm

我正在我的应用程序中使用RelayCommand.将代码放在viewmodel中非常棒,但是如何将键击绑定到我的命令?

RoutedUICommand具有InputGestures属性,当我按下击键时会自动调用该命令.(作为一个额外的好处,它甚至可以在MenuItem中显示击键.)不幸的是,RoutedUICommand的额外属性没有可重复使用的界面,所以我无法使RelayUICommand获得同样的魔力.

我已经尝试过使用InputBindings:

<Window.InputBindings>
    <KeyBinding Key="PageUp" Command="{Binding SelectPreviousLayerCommand}"/>
</Window.InputBindings>
Run Code Online (Sandbox Code Playgroud)

但这会让我产生运行时异常,因为KeyBinding.Command不是依赖属性.(实际上,它抱怨的是KeyBinding甚至不是DependencyObject.)由于我的RelayCommand是我的ViewModel上的属性(与RoutedUICommand设计的静态字段相反),数据绑定是我所知道的唯一方式从XAML引用它.

你们怎么解决这个问题?将击键绑定到RelayCommand的最佳方法是什么?

Mar*_*ann 17

我认为你不能从XAML那里做到这一点,原因正如你所描述的那样.

我最终在代码隐藏中做到了这一点.虽然它是代码,但它只是一行代码,而且仍然是声明性的,所以我可以忍受它.但是,我真的希望在下一版本的WPF中解决这个问题.

以下是我的一个项目的示例代码行:

this.InputBindings.Add(new KeyBinding(
    ((MedicContext)this.DataContext).SynchronizeCommand,
    new KeyGesture(Key.F9)));
Run Code Online (Sandbox Code Playgroud)

在这种情况下,SynchronizeCommand是RelayCommand的一个实例,并且(显然)F9会触发它.


jbe*_*jbe 14

KeyBinding类的Command属性不支持数据绑定.这个问题将在.NET 4.0中得到解决,您应该能够在即将推出的.NET 4.0 Beta 2版本中看到它.

  • 在http://tomlev2.wordpress.com/2009/10/26/vs2010-binding-support-in-inputbindings/上的文章中描述了绑定.NET 4.0中KeyBinding类的Command属性. (10认同)

Cam*_*and 10

您可以继承KeyBinding,添加CommandBinding设置Command属性的依赖项属性,然后像任何其他输入绑定一样将其添加到XAML.

public class RelayKeyBinding : KeyBinding
{
    public static readonly DependencyProperty CommandBindingProperty =
        DependencyProperty.Register("CommandBinding", typeof(ICommand), 
        typeof(RelayKeyBinding),
        new FrameworkPropertyMetadata(OnCommandBindingChanged));
    public ICommand CommandBinding
    {
        get { return (ICommand)GetValue(CommandBindingProperty); }
        set { SetValue(CommandBindingProperty, value); }
    }

    private static void OnCommandBindingChanged(
        DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var keyBinding = (RelayKeyBinding)d;
        keyBinding.Command = (ICommand)e.NewValue;
    }
}
Run Code Online (Sandbox Code Playgroud)

XAML:

<Window.InputBindings>
    <RelayKeyBinding 
        Key="PageUp" 
        CommandBinding="{Binding SelectPreviousLayerCommand}" />
</Window.InputBindings>
Run Code Online (Sandbox Code Playgroud)