【问题标题】:C# - How to handle XAML Keyboard in MVVM?C# - 如何在 MVVM 中处理 XAML 键盘?
【发布时间】:2013-12-06 16:11:59
【问题描述】:

直到现在,我都在使用 .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">

这里是 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;
        }
}

如何在 MVVM 中实现相同的功能? 因为据我了解,我们不能绑定方法,只能绑定属性,对吧?

【问题讨论】:

    标签: c# wpf xaml mvvm


    【解决方案1】:

    您似乎得到了答案,但这里有另一种解决方案。
    您可以使用i:interactionInputBindings 处理键盘事件。使用DatePicker 进行交互的一些示例如下:

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

    (请注意,i:Interaction 需要在窗口定义中添加下一行:)

    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    

    对于输入绑定:

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

    随意看看at my other answer,它讨论了i:interactionInputBindings,并指向另一篇关于处理关键事件的文章:up/down on datepicker,并讨论了/mvvm方法背后的代码。

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

    【讨论】:

    • +1。我正要发这个。无需使用“工具包”,效果很好。
    • 虽然这种方法没问题,但我看不出您如何处理 OnKeyUp 此处,以便将 PushToTalk 属性切换为 false,就像 OP 正在做的那样。
    【解决方案2】:

    输入处理是 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;
        }
    }
    

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

    【讨论】:

    • 虽然这可能有效,但 MVVM 与事件无关。一个“纯粹主义者”会向你报警:p
    • @Tico 错了。 MVVM 是关于不将业务逻辑和 UI 放在一起,而不是关于什么可以使用什么不能使用的无意义的任意限制。我的解决方案符合 MVVM,让 View 处理它的问题,同时将业务逻辑保留在 ViewModel 中。
    • 好的,我相信。但它不会与Command 模式冲突吗?我不是纯粹主义者。但 Ui/Logic 的分离也可以通过其他架构实现
    • 它确实与Command 模式冲突,但似乎没有办法在窗口本身上放置命令。据我所知,@Noctis 的答案不起作用,因为 Interaction.Triggers 不能卡在窗口上。 KeyDown/KeyUp 也没有 EventTrigger,所以不要朝那个方向走。
    【解决方案3】:

    以下方法用于处理 TextBox 中的“Enter”键:

    <TextBox Text="{Binding UploadNumber, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    <TextBox.InputBindings>
        <KeyBinding 
          Key="Enter" 
          Command="{Binding FindUploadCommand}" 
          CommandParameter="{Binding Path=Text, RelativeSource={RelativeSource AncestorType={x:Type TextBox}}}" />
    </TextBox.InputBindings>
    

    【讨论】:

      猜你喜欢
      • 2019-05-01
      • 1970-01-01
      • 2016-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-22
      • 2020-06-07
      相关资源
      最近更新 更多