如何在WPF中使用Prism 6处理ViewModel的按键事件?

3
我有一个情况,需要处理按键事件,可以是 A-Z、0-9 中的任意一个,但我需要在 ViewModel 中处理。按下的键应该被传递到 ViewModel 中。我使用的是 Prism 6.0,所以 View1ViewModel 与 view1 自动关联。
我知道对于特定的按键,我可以进行处理,但如何处理所有按键呢?
在 ViewModel 中,我有一个名为“KeyPressed”的属性,我尝试在 code-behind 中使用以下代码:
private void Window_PreviewKeyUp(object sender, KeyEventArgs e)
{
    _mainWindowViewModel.KeyPressed = e.Key;
}

但是,这段代码没有像Prism框架中的ViewModel和View绑定那样更新View1ViewModel。我尝试使用Interaction,将以下代码放置在根Grid部分中。
<i:Interaction.Triggers >
   <i:EventTrigger EventName="KeyUp">
      <i:InvokeCommandAction Command="{Binding KeyUpEventCommand}" 
        CommandParameter="..."/>
    </i:EventTrigger>
</i:Interaction.Triggers>

事件已被触发,但由于没有命令参数,所以它的值为空。 我需要传递一个命令参数,但不知道应该是什么! 在ViewModel中:
public DelegateCommand KeyUpEventCommand { get; private set; }

private string strAlphabet;
public string Alphabets
{
     get { return strAlphabet; }
     set { SetProperty(ref strAlphabet, value); }
}

public MainWindowViewModel(IEventAggregator eventAggregator)
{
     KeyUpEventCommand = new DelegateCommand(KeyUpEventHandler);
}

public void KeyUpEventHandler()
{
     //This logic can be changed
     if (Alphabets == "A")
     {
         // Perform some action
     }
     if (Alphabets == "B")
     {
         // Perform some other action
     }
}

有什么想法或建议可以处理这个问题吗?

“ doesn't update the View1ViewModel ”这句话是什么意思?发生了什么?是 PreviewKeyUp 事件处理程序被调用,但视图模型的 KeyPressed 属性的 setter 没有被调用,还是其他情况? - mm8
我已经更新了我的问题,KeyUpEventCommand被触发了,但它不包含按键的值。 - Debhere
在视图模型类中,KeyUpEventCommand 的定义是什么? - mm8
你能添加你的CommandParameter吗? - leapold
我已经更新了我的代码。 - Debhere
2个回答

5
命令属性的类型应为 DelegateCommand<KeyEventArgs>
public DelegateCommand<KeyEventArgs> KeyUpEventCommand { get; private set; }

private string strAlphabet;
public string Alphabets
{
    get { return strAlphabet; }
    set { SetProperty(ref strAlphabet, value); }
}

public MainWindowViewModel(IEventAggregator eventAggregator)
{
    KeyUpEventCommand = new DelegateCommand<KeyEventArgs>(KeyUpEventHandler);
}

public void KeyUpEventHandler(KeyEventArgs args)
{
    //...
}

同时确保您正在使用Prism自己的InvokeCommandAction类,并且不要设置其CommandParameter属性:

xmlns:prism="http://prismlibrary.com/"
...
<i:Interaction.Triggers >
    <i:EventTrigger EventName="PreviewKeyDown">
        <prism:InvokeCommandAction Command="{Binding KeyUpEventCommand}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

默认情况下,应将KeyEventArgs作为命令参数传递。


太好了!这正是我需要的。非常感谢您的回答。但是,您能否解释一下为什么如果我使用其他键,比如我先按A,然后想按B再按C……prism:InvokeCommandAction就不会触发呢?每次按键时,KeyUpEventCommand都应该被执行。但事实并非如此。 - Debhere
1
因为该类是 Blend SDK 的一部分,不支持将 EventArgs 传递给命令。 - mm8

1
尝试使用 KeyTriger。
    <i:Interaction.Triggers>
        <ei:KeyTrigger Key="Escape">
            <i:InvokeCommandAction Command="{Binding KeyDownCommand}" />
        </ei:KeyTrigger>
    </i:Interaction.Triggers>





public ICommand KeyDownCommand
    {
        get { return new RelayCommand(KeyboardKeyDownCommand, true); }
    }

    private void KeyboardKeyDownCommand()
    {
        ///code
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接