Self-subscribe to PropertyChanged or addition method call in setter?

c#, inotifypropertychanged, mvvm, wpf

Solution

I would definitely go for the first method:

- it's clear

- it's explicit in its flow and intention

- it avoids weird (imo) self subscription

The "benefits" of second, which lets you use autogenerated properties is not worth the clearness of the execution flow of the firs case, imo.

Hope this helps.

Problem

Maybe here is already such question, but I didn't find it. I have MVVM application, and in my `ViewModel` I have to do some additional actions on changes of some properties (for example, if `View` changes them). Which approach is better on your mind and why? 1st - Add `AdditionalAction` call to setter ``` public class ViewModel: INotifyPropertyChanged { private int _MyProperty; public int MyProperty { get { return _MyProperty; } set { if (_MyProperty == value) return; _MyProperty = value; RaisePropertyChanged(() => MyProperty); // --- ADDITIONAL CODE --- AdditionalAction(); } } } ``` 2nd - Self-subscribe to INotifyPropertyChanged ``` public class ViewModel: INotifyPropertyChanged { public ViewModel() { // --- ADDITIONAL CODE --- PropertyChanged += OnPropertyChanged; } private int _MyProperty; public int MyProperty { get { return _MyProperty; } set { if (_MyProperty == value) return; _MyProperty = value; RaisePropertyChanged(() => MyProperty); } } void PropertyChanged(object sender, PropertyChangedEventArgs e) { // --- ADDITIONAL CODE --- if (e.PropertyName == "MyProperty") AdditionalAction(); } } ``` Imagine, that I don't have performance problem or 10'000 objects. It's just View and ViewModel. What is better? First code is "smaller" and has less overhead, but the second (on my mind) is more clear and I can use code snippets for auto-generation properties' code. Even more - in the 2nd case I can write in event handler something like: ``` On.PropertyChanged(e, p => p.MyProperty, AdditionalAction); ``` where `On` is class-helper. So, what is better on your mind and why? UPDATED: OK, it looks like I found yet one approach: 3rd - add "extension point" in RaisePropertyChanged: ``` public class NotificationObject : INotifyPropertyChanged { void RaisePropertyChanged(Expression<...> property) { // ... Raise PropertyChanged event if (PropertyChanged != null) // blah-blah // Call extension point OnPropertyChanged(property.Name); } public virtual OnPropertyChanged(string propertyName) { } } public class ViewModel: NotificationObject { private int _MyProperty; public int MyProperty { get { return _MyProperty; } set { if (_MyProperty == value) return; _MyProperty = value; RaisePropertyChanged(() => MyProperty); } } override OnPropertyChanged(string propertyName) { if (propertyName == "MyProperty") AdditionalAction(); } } ``` This way we don't use event, but all "additional actions" are called from the same "extension point". Is "one place for all addition actions" better than "not transparent workflow"?

Original source