C# 每当视图中的任何文本框发生更改时,对视图模型调用命令

C# 每当视图中的任何文本框发生更改时,对视图模型调用命令,c#,wpf,mvvm,C#,Wpf,Mvvm,我有几个视图,每个视图都有几个XAMLTextBox实例。每个视图的文本属性都绑定到表示视图的可视数据模型的值对象 <TextBox Text="{Binding Path=SelectedItem.SomeValue, UpdateSourceTrigger=PropertyChanged}"/> 我有大约9或10个这样的盒子。我有一个类(ChangeModel),它跟踪哪些表单被更改(例如,用户输入了一个新值)。问题是绑定到TextBox的实际值对象。Text属性(在示例中

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

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

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

我想在XML中轻松添加一个绑定(可能在参考资料部分),每当任何
TextBox
更改时,该绑定都会在视图模型中调用一个命令。我想我可以用一个
DataTrigger
语句来实现这一点,但我不知道该怎么做


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

或者,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);
        }
    }
}
public类invokeCommandTextChanged:行为
{
公共静态从属属性CommandProperty=
Register(“命令”、typeof(ICommand)、typeof(InvokeCommandOnTextChanged));
公共静态从属属性CommandParameterProperty=
Register(“CommandParameter”、typeof(object)、typeof(InvokeCommandOnTextChanged));
公共ICommand命令
{
获取{return(ICommand)GetValue(CommandProperty);}
set{SetValue(CommandProperty,value);}
}
公共对象命令参数
{
获取{return GetValue(CommandParameterProperty);}
set{SetValue(CommandParameterProperty,value);}
}
受保护的覆盖无效附加()
{
base.onatached();
this.AssociatedObject.TextChanged+=OnTextChanged;
}
附加时受保护的覆盖无效()
{
base.OnDetaching();
this.AssociatedObject.TextChanged-=OnTextChanged;
}
私有void OnTextChanged(对象发送方,textchangedventargs e)
{
var命令=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>

另一种方法是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);
        }
    }
}
public类invokeCommandTextChanged:行为
{
公共静态从属属性CommandProperty=
Register(“命令”、typeof(ICommand)、typeof(InvokeCommandOnTextChanged));
公共静态从属属性CommandParameterProperty=
Register(“CommandParameter”、typeof(object)、typeof(InvokeCommandOnTextChanged));
公共ICommand命令
{
获取{return(ICommand)GetValue(CommandProperty);}
set{SetValue(CommandProperty,value);}
}
公共对象命令参数
{
获取{return GetValue(CommandParameterProperty);}
set{SetValue(CommandParameterProperty,value);}
}
受保护的覆盖无效附加()
{
base.onatached();
this.AssociatedObject.TextChanged+=OnTextChanged;
}
附加时受保护的覆盖无效()
{
base.OnDetaching();
this.AssociatedObject.TextChanged-=OnTextChanged;
}
私有void OnTextChanged(对象发送方,textchangedventargs e)
{
var命令=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>


那么您想为textbox创建一个隐式样式,使用带有TextChanged的eventtrigger和调用ViewModel的InvokeCommandTriggerAction?我想这可能行得通,但我不知何故认为,不能将这些触发器放在一个样式中是有局限性的!所以可能会对您有所帮助…那么您希望textbox有一个隐式样式,使用带有TextChanged的eventtrigger和调用ViewModel的InvokeCommandTriggerAction?我想这可能行得通,但我不知何故认为,不能将这些触发器放在一个样式中是有局限性的!所以可能会帮助你。。。