What is the best way to react on a change of a property named foo of the view model (of unspecified type) in the code behind, assuming the view model implements INotifyPropertyChanged
correctly?
Usually one can bind control elements to view model properties and everything works. But in this case, this is not enough and I need to execute some lines of c# when the property changes.
One could listen to the corresponding event of the DataContext, but then, I have also handle changes of the DataContext itself. Another possible solution would be to introduce a DependencyProperty
in the code behind file. But isn't there a shorter way?
I would recommend avoiding this when possible. If it is necessary, subscribe to the PropertyChanged
event.
I would put this code in the code behinds constructor.
INotifyPropertyChanged viewModel = (INotifyPropertyChanged)this.DataContext;
viewModel.PropertyChanged += (sender, args) => {
if (!args.PropertyName.Equals("foo"))
return;
// execute code here.
};
Maintainability tip If you know for sure that the data context is a type that has the property, cast to that type and use the nameof
operator rather than a magic string.
Edit (reacting to datacontext changes)
You should be able to subscribe to the DataContextChanged event to handle changes in the data context.
INotifyPropertyChanged previous;
// constructor
public SomeCodeBehindClass()
{
previous = (INotifyPropertyChanged)this.DataContext;
DataContextChanged += (sender, args) => SubscribeToFooChanges((INotifyPropertyChanged)args.NewValue);
SubscribeToFooChanges(previous);
}
// subscriber
private void SubscribeToFooChanges(INotifyPropertyChanged viewModel)
{
if (previous != null)
previous.PropertyChanged -= FooChanged;
previous = viewModel;
if (viewModel != null)
viewModel.PropertyChanged += FooChanged;
}
// event handler
private void FooChanged (object sender, PropertyChangedEventArgs args)
{
if (!args.PropertyName.Equals("foo"))
return;
// execute code here.
}
Possible solution, in you code behind you could do this
(((dynamic)DataContext).foo as ObservableCollection<object>).CollectionChanged += (s, e) =>
{
if (e.Action == NotifyCollectionChangedAction.Replace)
{
}
else
{
//and so on
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With