Refactoring PropertyChangedEventHandler

In my user interface code, I have many classes with the same base skeleton:

  • comes from INotifyPropertyChanged
  • contains the following code:

    void NotifyPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } public event PropertyChangedEventHandler PropertyChanged; 

This seems like a great chance to turn into a class and extract from it instead of INotifyPropertyChanged, but unfortunately C # does not support multiple inheritance, so it will not work. Any ideas on how to reorganize this type of code?

+4
source share
5 answers

Can't you just put this code in your class superclass?

  • Object
    • Your concrete class NotifyPropertyChanged <- Paste here
      • Regardless of what your view model has inherited (and whether you have stopped using multiple inheritance
        • Your specific view model
        • Another specific viewing model

Most MVVM Frameworks provide you with such a class.

Due to the rules for accessing events, you unfortunately cannot attribute this to the extension method without reflection.

+1
source

Perhaps you can use something like this:

 class A1 : INotifyPropertyChanged { private string _myProperty; private static Expression<Func<A1, string>> myProperty = _ => _.MyProperty; public string MyProperty { get { return _myProperty; } set { _myProperty = value; InvokePropertyChanged(myProperty); } } public event PropertyChangedEventHandler PropertyChanged; private void InvokePropertyChanged<T>(Expression<Func<A1, T>> property) { PropertyChangedEventHandler Handler = PropertyChanged; if (Handler != null) { MemberExpression expression = (MemberExpression)property.Body; Handler(this, new PropertyChangedEventArgs(expression.Member.Name)); } } } 

This will significantly reduce future code changes;)

Or you can use the Postsharp plugin, which automatically implements INotifyPropertyChanged .

+1
source

A common practice is to create a base class that implements INotifyPropertyChanged, for example:

 public abstract class ViewModelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } } 

Then your classes will be derived from this, and you can call OnPropertyChanged when you want to notify changes about the value of the property:

 public class PersonViewModel : ViewModelBase { public PersonViewModel(Person person) { this.person = person; } public string Name { get { return this.person.Name; } set { this.person.Name = value; OnPropertyChanged("Name"); } } } 
+1
source

These are 4 lines of code that will never change. Create a fragment!

0
source

This is probably a little help, but you can use the params keyword so that you can change more than one property at a time.

  public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertiesChanged(params string[] Properties) { if (PropertyChanged != null) foreach (string property in Properties) PropertyChanged(this, new PropertyChangedEventArgs(property)); } 

This reduces the number of lines you use when notifying you of future property changes. So you use:

NotifyPropertiesChanged ("foo", "bar");

Instead:

NotifyPropertyChanged ("Foo"); NotifyPropertyChanged ("bar");

Otherwise, I agree with Anders' suggestion that it be moved around the inheritance tree, it would probably be better.

0
source

Source: https://habr.com/ru/post/1300044/


All Articles