【问题标题】:How to handle a key press event in ViewModel using Prism 6 in WPF?如何在 WPF 中使用 Prism 6 处理 ViewModel 中的按键事件?
【发布时间】:2017-07-01 19:46:47
【问题描述】:

我有一种情况需要处理按键事件,它可以是 A-Z、0-9 中的任何一个,但我需要在 ViewModel 中处理它。按下哪个键应该传递给 ViewModel。我使用的是 prism 6.0,因此 View1ViewModel 与 view1 自动连接。

我知道对于特定的键我可以处理,但如何对所有键执行相同的操作。

我在 ViewModel "KeyPressed" 中有一个属性,我在代码隐藏中尝试了以下代码

private void Window_PreviewKeyUp(object sender, KeyEventArgs e)
{
    _mainWindowViewModel.KeyPressed = e.Key;
}

但是此代码不会像在 Prism 框架视图模型中那样更新 View1ViewModel,并且视图绑定是通过框架进行的。 我尝试过使用交互,我把下面的代码放在根Grid 部分。

<i:Interaction.Triggers >
   <i:EventTrigger EventName="KeyUp">
      <i:InvokeCommandAction Command="{Binding KeyUpEventCommand}" 
        CommandParameter="..."/>
    </i:EventTrigger>
</i:Interaction.Triggers>

事件被触发,但由于没有 Command 参数,所以它为空。我需要传递一个commandParameter,但不知道它应该是什么!

在 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
     }
}

任何想法/建议我该如何处理?

【问题讨论】:

  • “不更新 View1ViewModel”究竟是什么意思?发生什么了? PreviewKeyUp 事件处理程序是否被调用但视图模型的 KeyPressed 属性的设置器没有被调用或什么?
  • 我已经更新了我的问题,KeyUpEventCommand 被触发,但它不包含按键的值。
  • 视图模型类中的KeyUpEventCommand是如何准确定义的?
  • 你能添加你的CommandParameter吗?
  • 我已经更新了我的代码。

标签: c# wpf mvvm prism-6


【解决方案1】:

命令属性的类型应该是DelegateCommand&lt;KeyEventArgs&gt;:

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应该默认作为命令参数传递。

【讨论】:

  • 完美!!!这就是我所需要的。非常感谢您的回答。但是您能否说明一下为什么 prism:InvokeCommandAction 如果我使用其他键不会触发,比如我先按 A 然后我想按 B 然后按 C ...每次我按一个键时都应该执行 KeyUpEventCommand。但这并没有发生。
  • 因为该类是 Blend SDK 的一部分,不支持将 EventArgs 传递给命令。
【解决方案2】:

试试 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
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-26
    • 2013-07-04
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 2021-12-26
    • 1970-01-01
    相关资源
    最近更新 更多