views:

94

answers:

5

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 these classes are very simple. Now I need to implement INotifyPropertyChanged interface for them which will increase the amount of code a lot. Is there any class that I can inherit from to avoid writing all this boring code? I image that I can inherit my classes from some class and decorate the properties with some attributes and it will do the magic. Is that possible?

I'm well aware of Aspect Oriented Programming, but I'd rather do it object oriented way.

A: 

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.

Jon Skeet
+6  A: 

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;
    }
}
Marc Gravell
+3  A: 

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

leppie
A: 

Using code gen (say, T4) is another way. Check the discussion at: http://stackoverflow.com/questions/2968406/automatic-inotifypropertychanged-implementation-through-t4-code-generation.

I use this method, and it works well.

codekaizen
+1  A: 

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.

Dr Herbie