如何使用MVVM Light检测TextBox中的按键

时间:2017-11-06 01:13:13

标签: c# wpf xaml mvvm mvvm-light

在我的ViewModel中,如何在textBox中输入文本时检测到哪个键被按下了?

在简单的WPF / C#中,我这样做......

XAML文件

<TextBox x:Name="myInputField" KeyDown="inputField_KeyDown"/>

Codebehind .xaml.cs

private void inputField_KeyDown(object sender, KeyEventArgs e)
{
    if (Keyboard.IsKeyDown(Key.Enter)) {
        // do something
    }
}

编辑:

仅供参考 - 我要做的是为回车键创建一个快捷方式。

3 个答案:

答案 0 :(得分:2)

有几种方法可以解决这个问题。第一种方法是更适合MVVM,我们只检测绑定到Text的{​​{1}}值的变化:

在XAML中:

TextBox

在VM中

<TextBox x:Name="myInputField", 
         Text="{Binding MyText, UpdateSourceTrigger=PropertyChanged}" />

或者,为了更直接地回答您提出的问题,如果您必须依赖于检测文本框中的按键,您应该利用private string myText; public string MyText { get { return myText; } set { if (Set(nameof (MyText), ref myText, value)) { // the value of the text box changed.. do something here? } } } that you can hook in with MVVMLight

在XAML中:

EventToCommand

修改

此外,您还可以绑定到文本框上的KeyBinding命令:

xmlns:cmd="http://www.galasoft.ch/mvvmlight"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

...

<TextBox ....
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="KeyDown">
            <cmd:EventToCommand Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext.KeyDownCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>    
</TextBox>

另一种选择是在视图中继续处理KeyDown事件,但在代码隐藏中调用ViewModel方法:

答案 1 :(得分:2)

据我了解,您实际上不希望将Key发送给ViewModel。您只想触发ViewModel内的某些内容。

EventAggregator可能是您的解决方案,在KeyDown事件中,您在VM中触发事件而不知道VM并且您传递了任何您想要的内容,有几种方法可以执行此操作。

如果你使用MVVMLight这样的框架,Prism他们可能有自己的实现,如果你没有,那么就有一个简单的tutorial。 (这不是唯一的方法,当您搜索observer pattern

时,您可以找到不同的实现

在您if的{​​{1}}内,您调用来自Publish的{​​{1}}方法。所有订阅者都可以使用您选择的参数获得。

通过这种方式,您可以随时随地与EventAggregator进行通信。

答案 2 :(得分:0)

我个人创建了一个Behavior,如下所示:

public class KeyUpToCommandBehaviour : Behavior<UIElement>
{
    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
        "Command", typeof(ICommand), typeof(KeyUpToCommandBehaviour), new PropertyMetadata(default(ICommand)));

    public ICommand Command
    {
        get { return (ICommand) GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    public static readonly DependencyProperty KeyProperty = DependencyProperty.Register(
        "Key", typeof(Key), typeof(KeyUpToCommandBehaviour), new PropertyMetadata(default(Key)));
    private RoutedEventHandler _routedEventHandler;

    public Key Key
    {
        get { return (Key) GetValue(KeyProperty); }
        set { SetValue(KeyProperty, value); }
    }

    protected override void OnAttached()
    {
        base.OnAttached();
        _routedEventHandler = AssociatedObject_KeyUp;

        AssociatedObject.AddHandler(UIElement.KeyUpEvent, _routedEventHandler, true);
    }

    void AssociatedObject_KeyUp(object sender, RoutedEventArgs e)
    {
        var keyArgs = e as KeyEventArgs;

        if (keyArgs == null)
            return;

        if(keyArgs.Key == Key)
            Command?.Execute(null);
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.RemoveHandler(UIElement.KeyUpEvent, _routedEventHandler);
    }
}

然后将其用作

<TextBox ....
    <i:Interaction.Behaviors>
        <attachedBehaviors:KeyUpToCommandBehaviour Key="Enter" Command="{Binding OpenFxTradeTargetingWizardCommand}"/>
    </i:Interaction.Behaviors>
</TextBox>