如何从ViewModel进行绑定

时间:2011-11-24 19:24:29

标签: silverlight data-binding mvvm mvvm-light

我正在尝试捕获在文本框中按下的Enter键,以便我可以启动对服务器的更新。它不起作用,所以我把问题简化为简单的elemet。

在这个例子中,似乎每次击键都没有发生绑定,但稍后会发生。我需要在按下回车键时完成绑定。请考虑VM中的以下XAML和功能。

这是文本框的XAML

<TextBox Text="{Binding TextValue, Mode=TwoWay}" Height="23" Width="300">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="KeyDown">
            <cmd:EventToCommand Command="{Binding KeyDownCommand}"
                PassEventArgsToCommand="True" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBox>

KeyDownCommand按预期触发,但该值尚未在TextValue属性中。如果我第二次进入,那么该值是在属性中吗?这是KeyDownCommand。 ViewModel的构造函数正确设置了keyDownCommand。

public RelayCommand<RoutedEventArgs> KeyDownCommand { get; private set; }
private void KeyDownAction(RoutedEventArgs eventArg)
{
    var source = eventArg.OriginalSource as FrameworkElement;
    var e = eventArg as KeyEventArgs;
    if (source != null && e != null && e.Key== Key.Enter)
    {
        e.Handled = true;
        MessageBox.Show(TextValue);
    }
}

似乎我需要的是一种在按下Enter键时将TextBox的Text“发布”回VM的TextValue属性的方法。或者还有其他我想念的东西。

2 个答案:

答案 0 :(得分:2)

尝试在绑定时将UpdateSourceTrigger设置为PropertyChanged,如下所示:

<TextBox Text="{Binding TextValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Height="23" Width="300">

现在每次更改文本时都会更新视图模型属性。

<强>更新

对于Silverlight,作为UpdateSourceTrigger的替代,您可以使用以下简单行为,在文本发生更改时更新绑定源:

public class TextChangedUpdateSourceBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.TextChanged += OnTextChanged;
    }

    private void OnTextChanged(object sender, TextChangedEventArgs e)
    {
        var bindingExpression = AssociatedObject.GetBindingExpression(TextBox.TextProperty);

        if (bindingExpression != null)
        {
            bindingExpression.UpdateSource();
        }
    }
}

像这样使用:

<TextBox Text="{Binding TextValue, Mode=TwoWay}" Height="23" Width="300">
    <i:Interaction.Behaviors>
        <b:TextChangedUpdateSourceBehavior />
    </i:Interaction.Behaviors>
</TextBox>

答案 1 :(得分:1)

我提出这个问题的时间,而不是我的答案。

这是更正后的KeyDownAction

private void KeyDownAction(RoutedEventArgs eventArg)
{
    var source = eventArg.OriginalSource as FrameworkElement;
    source.GetBindingExpression(TextBox.TextProperty).UpdateSource();
    var e = eventArg as KeyEventArgs;
    if (source != null && e != null && e.Key== Key.Enter)
    {
        e.Handled = true;
        MessageBox.Show(TextValue);
    }
}

现在,当我输入它时,我意识到我正在“破坏”模式,因为现在我的ViewModel更多地了解它应该的视图。