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