Wpf 在文本框MVVM内按键

Wpf 在文本框MVVM内按键,wpf,data-binding,mvvm,Wpf,Data Binding,Mvvm,我刚刚开始使用MVVM,我很难弄清楚如何将文本框中的按键绑定到视图模型中的ICommand。我知道我可以在代码背后做到这一点,但我尽量避免这样做 更新:如果你有blend sdk或者你的交互dll没有问题,那么到目前为止的解决方案都很好。除了必须使用blend sdk之外,还有其他更通用的解决方案吗?最好的选择可能是使用。如果您有Blend SDK,那么行为类会使这变得更简单 例如,可以很容易地修改此命令,以便在每次按键时触发ICommand,而不是单击Enter上的按钮。从事件处理后的代码到M

我刚刚开始使用MVVM,我很难弄清楚如何将文本框中的按键绑定到视图模型中的ICommand。我知道我可以在代码背后做到这一点,但我尽量避免这样做


更新:如果你有blend sdk或者你的交互dll没有问题,那么到目前为止的解决方案都很好。除了必须使用blend sdk之外,还有其他更通用的解决方案吗?

最好的选择可能是使用。如果您有Blend SDK,那么
行为
类会使这变得更简单


例如,可以很容易地修改此命令,以便在每次按键时触发ICommand,而不是单击Enter上的按钮。

从事件处理后的代码到MVVM命令的最简单转换可能是来自的触发器和操作

下面是一段代码,演示了如何使用命令处理文本框内的按键按下事件:

    <TextBox>
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="KeyDown">
                <si:InvokeDataCommand Command="{Binding MyCommand}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </TextBox>

首先,如果您想绑定RouteDicom命令并且很简单,只需添加到UIElement.InputBindings集合:

<TextBox ...>
  <TextBox.InputBindings>
    <KeyBinding
      Key="Q"
      Modifiers="Control" 
      Command="my:ModelAirplaneViewModel.AddGlueCommand" />
两个附加属性的替代方法是创建CommandBinding子类,该子类接收路由命令并激活绑定命令:

<Window.CommandBindings>
  <my:CommandMapper Command="my:RoutedCommands.AddGlue" MapToCommand="{Binding AddGlue}" />
  ...
就我的口味而言,我更喜欢使用附加属性解决方案,因为它不需要太多代码,并且不需要将每个命令声明两次(作为RoutedCommand和ViewModel的属性)。支持代码只出现一次,并且可以在所有项目中使用


另一方面,如果你只是在做一个一次性的项目,并且不希望重用任何东西,那么就连CommandMapper都可能是杀伤力过大。正如您所提到的,可以简单地手动处理事件。

优秀的WPF框架完美地解决了这个问题

        <TextBox cm:Message.Attach="[Gesture Key: Enter] = [Action Search]" />


语法[Action Search]绑定到视图模型中的方法。根本不需要ICommands。

如果我只想让命令在特定的键上触发怎么办?如果您的触发器变得更具体,您必须实现自己的。例如,带有属性键的KeyPressTrigger仅在按下指定键时才会触发(在其上面的InvokeDataCommand代码段中执行指定的操作)。出于好奇,为什么要尝试避免使用代码隐藏?因为我想要不绑定到特定视图模型的可重用组件。似乎在.net 4.0中,KeyBinding的命令可以绑定到viewmodel中的命令。CommandBinding不是DependencyObject,不能在其上声明DependencyProperty。这个解决方案不正确吗?有趣的是,我真的不喜欢他们没有为此使用标记扩展。而是解析字符串。@Kugel:+1。美联社:我不知道什么叫“美丽”。我不喜欢神奇的字符串。有趣的是,搜索不需要在视图模型中声明。它也可以在视图模型的一个祖先视图模型中声明。
<Window.CommandBindings>
  <my:CommandMapper Command="my:RoutedCommands.AddGlue" MapToCommand="{Binding AddGlue}" />
  ...
public class CommandMapper : CommandBinding
{
  ... // declaration of DependencyProperty 'MapToCommand'

  public CommandMapper() : base(Executed, CanExecute)
  {
  }
  private void Executed(object sender, ExecutedRoutedEventArgs e)
  {
    if(MapToCommand!=null)
      MapToCommand.Execute(e.Parameter);
  }
  private void CanExecute(object sender, CanExecuteRoutedEventArgs e)
  {
    e.CanExecute =
      MapToCommand==null ? null :
      MapToCommand.CanExecute(e.Parameter);
  }
}
        <TextBox cm:Message.Attach="[Gesture Key: Enter] = [Action Search]" />