How to avoid implementing INotifyPropertyChanged manually

后端 未结 7 1684
名媛妹妹
名媛妹妹 2021-01-05 02:44

Is there some way to avoid this. I have a lot of classes that are bound to DataGridViews and they are just simple collection of properties with default getter and setter. So

相关标签:
7条回答
  • 2021-01-05 02:59

    Create a container base class, eg:

    abstract class Container : INotifyPropertyChanged
    {
      Dictionary<string, object> values;
    
      protected object this[string name]
      {
        get {return values[name]; }
        set 
        { 
          values[name] = value;
          PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
      }
    }
    
    class Foo : Container
    {
      public int Bar 
      {
        {get {return (int) this["Bar"]; }}
        {set { this["Bar"] = value; } }
      }
    }
    

    Note: very simplified code

    0 讨论(0)
  • 2021-01-05 03:05

    Using code gen (say, T4) is another way. Check the discussion at: Automatic INotifyPropertyChanged Implementation through T4 code generation?.

    I use this method, and it works well.

    0 讨论(0)
  • 2021-01-05 03:14

    Without AOP, I don't think there is an easy way to retrofit this to your existing classes. However you do it, you're at the very least going to have to change all your properties.

    I use a base class inheriting INotifyPropertyChanged with an OnPropertyChanged(string propertyName) method to fire the event. I then use a Visual Studio Code snippet to create properties that automatically call OnPropertyChanged in the property setter.

    0 讨论(0)
  • 2021-01-05 03:18

    It depends; you could use PostSharp to write such an attribute that is re-written by the weaver; however, I would be tempted to just do it manually - perhaps using a common method for handling the data updates, i.e.

    private string name;
    public string Name {
        get { return name; }
        set { Notify.SetField(ref name, value, PropertyChanged, this, "Name"); }
    }
    

    with:

    public static class Notify {
        public static bool SetField<T>(ref T field, T value,
             PropertyChangedEventHandler handler, object sender, string propertyName)
        {
            if(!EqualityComparer<T>.Default.Equals(field,value)) {
                field = value;
                if(handler!=null) {
                    handler(sender, new PropertyChangedEventArgs(propertyName));
                }
                return true;
            }
            return false;
        }
    }
    
    0 讨论(0)
  • 2021-01-05 03:18

    I have just found ActiveSharp - Automatic INotifyPropertyChanged, I have yet to use it, but it looks good.

    To quote from it's web site...


    Send property change notifications without specifying property name as a string.

    Instead, write properties like this:

    public int Foo
    {
        get { return _foo; }
        set { SetValue(ref _foo, value); }  // <-- no property name here
    }
    

    Note that there is no need to include the name of the property as a string. ActiveSharp reliably and correctly figures that out for itself. It works based on the fact that your property implementation passes the backing field (_foo) by ref. (ActiveSharp uses that "by ref" call to identify which backing field was passed, and from the field it identifies the property).

    0 讨论(0)
  • 2021-01-05 03:20

    If you're amenable to AOP, you could try using PostSharp. Search for PostSharp INotifyPropertyChanged and you'll find lots of articles explaining it, such as this and this.

    0 讨论(0)
提交回复
热议问题