Properties with property changed event, part 2

Last time I talked about properties with a changed event, I described the traditional pattern of having one event per property. But there is a disadvantage to that approach: since an event needs storage for a delegate, this technique wastes a considerable amount of memory if nobody subscribes to the events.

Say you have 10 properties of reference types with a simple backing variable each. On a 32 bit machine, those will take 40 bytes plus the storage of the actual objects (if any). If each of these properties has an associated event, that’s 40 additional bytes (plus storage for the delegate objects, if any).

If you want to monitor if anything changes to the object, no matter which property it is that actually changes, you need to subscribe to all 10 events, and that’s going to create 10 delegate objects.

The System.ComponentModel.INotifyPropertyChanged interface provides an interesting alternative. It declares just one event:

public interface INotifyPropertyChanged
{
    event PropertyChangedEventHandler PropertyChanged;
}

A PropertyChangedEventHandler is an event handler that takes an object (sender) and  a PropertyChangedEventArgs, an EventArgs with an additional string PropertyName property.

How do we use this interface? Say I have a class Customer with two string properties: Name and City. It would look like this:

using System;
using System.ComponentModel;

class Customer : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, e);
        }
    }

    private string name;

    public string Name
    {
        get { return name; }
        set
        {
            if (value != name)
            {
                name = value;
                OnPropertyChanged(new PropertyChangedEventArgs(“Name”));
            }
        }
    }

    private string city;

    public string City
    {
        get { return city; }
        set
        {
            if (value != city)
            {
                city = value;
                OnPropertyChanged(new PropertyChangedEventArgs(“City”));
            }
        }
    }
}

Even though there are two properties, there is only one event. The advantages: less code, less memory usage. There are disadvantages as well though. If you’re interested only in changes to the Name property, your event handler needs to test the PropertyName in the PropertyChangedEventArgs passed to you. And you may get a lot of calls notifying you of changes to properties your aren’t interested in. On the sending side, be careful with rename refactorings, since the strings being passed around won’t be refactored by Visual Studio.

Nevertheless, this approach is becoming the dominant technique for data binding scenarios. In fact, the new Linq to SQL generated classes use this approach as well. So you might just as well get accustomed to it.

Advertisements

5 Responses to “Properties with property changed event, part 2”


  1. 1 Nisar Khan March 11, 2007 at 2:52 am

    hi, can you show me how do you implement the Customer class ?

    please email me, thank you so much.

    -Nisar

  2. 2 Rob FireGarden July 5, 2007 at 7:19 pm

    Can you show me how to implement a customer class? Nisar you are in the wrong place at the wrong time buddy. LOL.

    Hey Kris great post very relevant to whats going on. I will use a hybird of both approaches. I will have a class containing a few member classes. The member classes will all raise events. Those events will be consumed by the parent which in turn will raise INotifiyPropertyChanged.

    Any thoughts on that approach?

    Rob

  3. 3 Kris Vandermotten July 5, 2007 at 10:29 pm

    Rob,

    I’m not sure I understand what you mean by that. Could you post an example, e.g. show me how you would implement the Customer class using that approach (seriously, no joke intended)?

    Nevertheless, it looks like you’ll have some sort of indirection on your properties and events. I can see some drawbacks there: it’s unlikely to increase developer productivity or runtime performance.

    But again, show me a small example and we’ll discuss.

    Kris.

  4. 4 mpgrewal June 28, 2008 at 5:19 pm

    I’m using the same technique. But in my case, even when I’m changing the value of a property, but inside the event handler the PropertyName is always null.

  5. 5 Vineet September 24, 2008 at 3:07 pm

    Hers is a question:

    I’ve registered a property change event, and that property is being changed in code. Is there any other way to avoid calling of property change event for property change in code, except keeping a check for it?
    example:
    combo.Selected Index = 5;
    calls the selected index change event handler.
    Can I differentiate if the change if due to UI or from code?
    Thanks and regards


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s





%d bloggers like this: