只要视图中的任何TextBox发生更改,就对视图模型调用命令

本文关键字:视图 模型 命令 调用 任何 TextBox | 更新日期: 2023-09-27 18:21:00

我有几个视图,每个视图都有几个XAML TextBox实例。每个的Text属性都绑定到一个值对象,该值对象表示视图的视觉数据模型。

<TextBox Text="{Binding Path=SelectedItem.SomeValue, UpdateSourceTrigger=PropertyChanged}"/>

我在一个表单中有大约9或10个这样的框。我有一个类(ChangeModel),它跟踪哪些表单被更改了(例如,用户输入了一个新值)。问题是绑定到TextBox.Text属性的实际值对象(在本例中为SelectedItem.SomeValue)无法访问ChangeModel

我想在XML中轻松添加一个绑定(可能在参考资料部分),每当TextBox发生变化时,该绑定都会调用视图模型中的命令。我想我可以用DataTrigger声明来做到这一点,但我不知道该怎么做

有人能描述一下当视图中的任何TextBox发生更改时,如何使用数据触发器或任何其他XAML机制来提醒视图模型吗?

只要视图中的任何TextBox发生更改,就对视图模型调用命令

除了Markus Hütter所说的,您还可以保存几行XAML并编写类似的自定义行为

public class InvokeCommandOnTextChanged : Behavior<TextBox>
{
    public static DependencyProperty CommandProperty =
        DependencyProperty.Register("Command", typeof(ICommand), typeof(InvokeCommandOnTextChanged));
    public static DependencyProperty CommandParameterProperty =
        DependencyProperty.Register("CommandParameter", typeof(object), typeof(InvokeCommandOnTextChanged));
    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }
    public object CommandParameter
    {
        get { return GetValue(CommandParameterProperty); }
        set { SetValue(CommandParameterProperty, value); }
    }
    protected override void OnAttached()
    {
        base.OnAttached();
        this.AssociatedObject.TextChanged += OnTextChanged;
    }
    protected override void OnDetaching()
    {
        base.OnDetaching();
        this.AssociatedObject.TextChanged -= OnTextChanged;
    }
    private void OnTextChanged(object sender, TextChangedEventArgs e)
    {
        var command = this.Command;
        var param = this.CommandParameter;
        if (command != null && command.CanExecute(param))
        {
            command.Execute(param);
        }
    }
}

然后,您可以将此行为用于您的文本框:

<TextBox>
    <i:Interaction.Behaviors>
        <b:InvokeCommandOnTextChanged Command="{Binding AddCommand}" />
    </i:Interaction.Behaviors>
</TextBox>