C# - 如何在MVVM中处理XAML键盘?

Elf*_*yer 7 c# wpf xaml mvvm

直到现在,我正在使用.xaml.cs来处理输入.

这是我的xaml头代码:

<Window x:Class="My_Windows_App.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:My_Windows_App.ViewModel"
Title="MainWindow" Height="600" Width="900"
Keyboard.KeyDown="keyDownEventHandler" Keyboard.KeyUp="keyUpEventHandler">
Run Code Online (Sandbox Code Playgroud)

这是MainWindow.xaml.cs代码的一部分:

public partial class MainWindow : Window
    {
        private bool pushToTalk;

        public void keyDownEventHandler(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.LeftCtrl)
                pushToTalk = true;
        }

        public void keyUpEventHandler(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.LeftCtrl)
                pushToTalk = false;
        }
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能在MVVM中实现同样的东西?因为据我所知,我们不能绑定一个方法,只有属性,对吧?

Noc*_*tis 22

似乎你得到了答案,但这是另一种解决方案.
您可以使用i:interaction和处理键盘事件InputBindings.使用DatePickerwith with interaction的一些示例将是:

<DatePicker Name="fancy_name_here" SelectedDate="{Binding your_date_property_here}">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="PreviewKeyDown">               
    <i:InvokeCommandAction Command="{Binding Path=TestMeCommand}" />
    </i:EventTrigger>
  </i:Interaction.Triggers>
</DatePicker>
Run Code Online (Sandbox Code Playgroud)

(请注意,您需要窗口定义中的下一行i:Interaction才能工作:)

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Run Code Online (Sandbox Code Playgroud)

并为输入绑定:

<DatePicker Name="fancy_name_here"  SelectedDate="{Binding your_date_property_here}">
  <DatePicker.InputBindings>
    <KeyBinding Key="Up" Modifiers="Shift" Command="{Binding your_command_name}" />
    <KeyBinding Key="Up" Modifiers="Alt" Command="{Binding TestMeCommand}" />       
    <KeyBinding Key="Up" Command="{Binding TestMeCommand}" />        
  </DatePicker.InputBindings>
</DatePicker>
Run Code Online (Sandbox Code Playgroud)

请随意查看我的其他答案,它讨论i:interaction并回顾InputBindings另一篇关于处理关键事件的文章:up/down on datepicker,并讨论/ mvvm方法背后的代码.

希望你会发现它们很有用.

  • +1.我准备发布这个.没有必要使用"工具包"并且工作得很好. (2认同)

Fed*_*gui 6

输入处理是 View 的问题,而不是 ViewModel 的问题,为什么要将其移至 ViewModel?

相反,将应用程序/业务逻辑委托给 ViewModel,同时在 View 中保留键盘输入处理:

public partial class MainWindow : Window
{
    private MyViewModel ViewModel;

    public MainWindow()
    {
        ViewModel = new MyViewModel();
    }


    public void keyDownEventHandler(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.LeftCtrl)
            ViewModel.PushToTalk = true;
    }

    public void keyUpEventHandler(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.LeftCtrl)
            ViewModel.PushToTalk = false;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意我如何将PushToTalk属性移动到 ViewModel,因为这实际上是应用程序逻辑的一部分,而不是 UI,同时将键盘事件保留在视图级别。这不会破坏 MVVM,因为您没有混合 UI 和应用程序逻辑,您只是将东西放在它们真正属于的地方。

  • 虽然这可能有效,但 MVVM 与事件无关。“纯粹主义者”会向你报警:p (2认同)
  • @Tico 错了。MVVM 不是将业务逻辑和 UI 放在一起,而不是关于可以使用什么和不可以使用的毫无意义的任意限制。我的解决方案符合 MVVM,让 View 处理它的问题,同时将业务逻辑保留在 ViewModel 中。 (2认同)