Reputation: 41064
I have a few views that each have several XAML TextBox
instances. The Text property of each is bound to a value object that represents the visual data model for the view.
<TextBox Text="{Binding Path=SelectedItem.SomeValue, UpdateSourceTrigger=PropertyChanged}"/>
I have about 9 or 10 of these boxes in a form. I have a class (ChangeModel
) that keeps track of which forms have been altered (e.g. the user has entered in a new value). The problem is the actual value object that is bound to the TextBox.Text
property (in the example that would be SelectedItem.SomeValue
) can't access the ChangeModel
.
I'd like to easily add a binding in the XML (maybe in the resources section) that will call a command in the view model whenever any TextBox
changes. I think I can do this with a DataTrigger
statement but I'm not sure how to go about it.
Can anyone describe how to use a data trigger or any other XAML mechanism to alert the view model whenever any TextBox
within that view is altered?
Upvotes: 1
Views: 286
Reputation: 675
Alternatively to that Markus Hütter said you can save a few lines of XAML and write custom behavior like this
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);
}
}
}
Then you can use this behavior with your textboxes:
<TextBox>
<i:Interaction.Behaviors>
<b:InvokeCommandOnTextChanged Command="{Binding AddCommand}" />
</i:Interaction.Behaviors>
</TextBox>
Upvotes: 1