Visual C# Developer Center > Visual C# Forums > Visual C# General > .Net 2.0 INotifyPropertyChanged Interface Implementation
Ask a questionAsk a question
 

Question.Net 2.0 INotifyPropertyChanged Interface Implementation

  • Thursday, July 27, 2006 3:48 PMindiantroy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Dear friends,

    In my current project I am using the CustomCollections with the help of BindingList<T> generic class to store the database records instead using DataSet objects as offline database identities.

    Now I do have a large number of property classes each having a large number of properties in it.

    I want to implement the INotifyPropertyChanged interface in every property class as follows:

    The purpose to implement the INotifyPropertyChanged interface is I want to inform the UI whenever any property change occurs and update the it accodingly. Also I need to inform the ListChanged event of the my BindingList<T> collection object using the PropertyChangedEvent of INotifyPropertyChanged interface. I know that the PropertyChangedEvent automatically raises the ListChanged event of the BindingList<T> object.

    I want to maintain a flag whose value will be false whenever the collection gets changed means any property value of any item in the collection gets changed.

    My code is like below:


     public class Customer :INotifyPropertyChanged
        {
                
            private int number;
           
            public int Number
            {
                get { return number; }
                set { number = value;if(value!=number) OnPropertyChanged("Number"); }
            }

            private string name;

            public string Name
            {
                get { return name; }
                set { name = value;if(value != name) OnPropertyChanged("Name"); }
            }

      public event PropertyChangedEventHandler PropertyChanged;

            private void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
    }

    Now what if my class has 100 properties then....

    Is there any way out so I dont need to write the same code like below again and again in each property's set method:

    if(value != name) OnPropertyChanged("Name");

    I dont want to write the above line for every property.

    So is it possible to do this using Reflection and subscribe for the event PropertyChanged for every property in the class in a single code block..

    I have seen such a code months ago on any website but can't recall it right now as that time I was not so serious and not knowing I might have to implement this in future:)

    Suggest me how to do this and put the code snippet if possible.

    THANKS in ADVANCE.

    Regards,
    Hardeek Thakkar

All Replies

  • Thursday, August 10, 2006 7:23 PMOmegaManMVP, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I had to do something similar ... for each of the properties, one should create an individual class/object which does the routine work you mention. Internally to that object it will hold the actual data which can be a int, string or whatever. Put plumbing in place to 1) check for a change and report to a consumer 2) what type of data is there 3)  do the event as described and 4) return the actual data.

    Once that is in place the toplevel class will uses those objects as its properties. When it extracts the data, the underlying object checks its status and does what you described above and returns the data.

    That way the process you mentioned is centralized, easier to maintain and robust. So whether one has three or three hundred properties they will all behave the same way.

    Hope this helps.

  • Thursday, February 07, 2008 2:19 PMdanwer Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Couldn't you solve this with AOP?

     

  • Thursday, February 07, 2008 2:46 PMPatrik LöwendahlMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

     

    This would certenly be a model case for AOP.

     

    I would go and have a look at an AOP framework like spring: http://www.springframework.net/download.html which by configruation can insert the kind of cross-cutting concerns you are after.

     

  • Friday, April 11, 2008 9:31 PMJohn Rusk Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    There's also another option, which you might find more convenient than an AOP framework. It's called ActiveSharp, and it gives you property change notification in a really easy-to-use format.

    Just write properties like this

    public int Foo
    {
       get { return _foo;}
       set { SetValue(ref _foo; value); }    // note: NO need to include property name here
    }

    and ActiveSharp takes care of the rest.  

    It's bascially a special case of AOP, just for properties, but it's easier to set up and use than an AOP framework.  It automatically sets itself up at runtime (without ever modifying or subclassing your code in any way).

    I've posted it on CodePlex, here: http://www.codeplex.com/ActiveSharp

  • Saturday, April 12, 2008 6:57 AMfrederikm Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    and yet another possibility is to use basic generic syntax..

     

    Honestly, IMHO i would avoid using AOP for this, as AOP is better suited to cross cutting concers as logging, exception handling, security and so on...

     

     

    Code Snippet

    public class Customer : INotifyPropertyChanged {

    private int number;

    public int Number {

    get { return number; }

    set { SetValue<int>(ref number, value, "Number"); }

    }

    private string name;

    public string Name {

    get { return name; }

    set { SetValue<string>(ref name, value, "Name"); }

    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName) {

    if (PropertyChanged != null)

    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

    }

     

    private void SetValue<T>(ref T destination, T value, string name) {

    destination = value;

    OnPropertyChanged(name);

    }

    }

     

     

  • Saturday, April 12, 2008 8:11 PMJohn Rusk Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    frederikm,

    I agree.  The approach I described above is exactly the same, except that you don't need to pass the property name to SetValue.  (ActiveSharp figures it out from the ref parameter).  This makes your properties easier to write and, perhaps more importantly, easier to refactor. If the property name is inside the set method, as string, then what happens if you rename the property but forget to change the string?  That's why I wrote ActiveSharp.

  • Sunday, April 13, 2008 8:06 AMfrederikm Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    John,

     

    I was unaware of your solution, checking it out now and it looks promising,

    I'll go over the codeplex code in a few days Wink

     

     

    Cheers

     

    Frederik