[c#] Raise an event whenever a property's value changed?

There is a property, it's named ImageFullPath1

public string ImageFullPath1 {get; set; }

I'm going fire an event whenever its value changed. I am aware of changing INotifyPropertyChanged, but I want to do it with events.

This question is related to c# .net events properties

The answer is


The INotifyPropertyChanged interface is implemented with events. The interface has just one member, PropertyChanged, which is an event that consumers can subscribe to.

The version that Richard posted is not safe. Here is how to safely implement this interface:

public class MyClass : INotifyPropertyChanged
{
    private string imageFullPath;

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

    protected void OnPropertyChanged(string propertyName)
    {
        OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }

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

    public event PropertyChangedEventHandler PropertyChanged;
}

Note that this does the following things:

  • Abstracts the property-change notification methods so you can easily apply this to other properties;

  • Makes a copy of the PropertyChanged delegate before attempting to invoke it (failing to do this will create a race condition).

  • Correctly implements the INotifyPropertyChanged interface.

If you want to additionally create a notification for a specific property being changed, you can add the following code:

protected void OnImageFullPathChanged(EventArgs e)
{
    EventHandler handler = ImageFullPathChanged;
    if (handler != null)
        handler(this, e);
}

public event EventHandler ImageFullPathChanged;

Then add the line OnImageFullPathChanged(EventArgs.Empty) after the line OnPropertyChanged("ImageFullPath").

Since we have .Net 4.5 there exists the CallerMemberAttribute, which allows to get rid of the hard-coded string for the property name in the source code:

    protected void OnPropertyChanged(
        [System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
    {
        OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }

    public string ImageFullPath
    {
        get { return imageFullPath; }
        set
        {
            if (value != imageFullPath)
            {
                imageFullPath = value;
                OnPropertyChanged();
            }
        }
    }

Similar questions with c# tag:

Similar questions with .net tag:

Similar questions with events tag:

Similar questions with properties tag: