Thursday, January 24, 2013

C# INotifyPropertyChanged Base Class Implementation

This topic is relative to C# INotifyProperyChanged Interface topic. So better you visit it first before proceeding in this topic.

The purpose of this topic is to create an inheritable PropertyNotifier class that can be used by any derive class of your application. You have to realize that putting base object in one file is good and that is the basic concept of object oriented programming. In this blog, we are also introducing the power of Inheritance part of the object oriented programming.

The class that we have in the previous topic C# INotifyProperyChanged Interface is below. All we have to do is to make a perfect spice, adjust some code so it will be usable by the derived class.

[Serializable]
public abstract class PropertyNotifier : INotifyPropertyChanged
{
    [field: NonSerialized]
    public event PropertyChangedEventHandler PropertyChanged;

    public PropertyNotifier()
        : base()
    {
    }

    private string __myProperty = string.Empty;
    public string MyProperty
    {
        get
        {
            return this.__myProperty;
        }
        set
        {
            this.__myProperty = value;
            this.OnPropertyChanged("MyProperty");
        }
    }

    #region INotifyPropertyChanged Members

    protected void OnPropertyChanged(string propertyName)
    {
        if (!object.ReferenceEquals(this.PropertyChanged, null))
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion
}

The first thing is to remove the MyProperty property as it is not needed anymore. Then we need to add an additional property named AllowRaiseEvent. This property should not call the OnPropertyChanged event as it is not notifying the derive class in every property value change, instead this property will be used to determine whether we are allowed to raise the event or not. Declare the accessor as protected so only derived class can change the value.

Then in the OnPropertyChanged event handler, we have to check whether the AllowRaiseEvent property is true or false. If it is true then we should call the PropertyChanged event, otherwise not.

Lastly, we have to set the AllowRaiseEvent property value to true in the constructor so the default will be allow raising of event. See our new class structure below.

[Serializable]
public abstract class PropertyNotifier : INotifyPropertyChanged
{
    #region Events

    [field: NonSerialized]
    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    public PropertyNotifier()
        : base()
    {
        this.AllowRaiseEvent = true;
    }

    #region Properties

    [XmlIgnore]
    protected bool AllowRaiseEvent
    {
        get;
        set;
    }

    #endregion

    #region INotifyPropertyChanged Members

    protected void OnPropertyChanged(string propertyName)
    {
        if (this.AllowRaiseEvent)
        {
            if (!object.ReferenceEquals(this.PropertyChanged, null))
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

    #endregion
}

Now deriving from this class is flexible. You can set the AllowRaiseEvent property whether you want to notify property value change or not. Additionally, you can call the OnPropertyChanged method to notify the property of value change. See below the class that inherit the PropertyNotifier class.

public abstract class BaseObject : PropertyNotifier
{
    public BaseObject()
    {
        base.AllowRaiseEvent = true;
    }

    private string __myProperty = string.Empty;
    public string MyProperty
    {
        get
        {
            return this.__myProperty;
        }
        set
        {
            this.__myProperty = value;
            base.OnPropertyChanged("MyProperty");
        }
    }
}

You will notice that we atleast have a little more flexible base notifier object.

Now we're done with the INotifyPropertyChanged interface topic. Next topic would be implementing a flexible BaseObject class.

No comments:

Post a Comment

Place your comments and ideas