Skip to content

NotificationInterception

Simon Cropp edited this page Jul 30, 2012 · 2 revisions

Introduction

Sometimes it is helpful to be able to intercept call to OnPropertyChanging. For example

  • Logging all property sets
  • Performing some action before or after OnPropertyChanging
  • Choose to not fire OnPropertyChanging under certain circumstances
  • Executing OnPropertyChanging on the UI thread

Enter PropertyChangingNotificationInterceptor

All the points above can be achieved by having a static class named PropertyChangingNotificationInterceptor in your assembly. The class should look as follows

public static class PropertyChangingNotificationInterceptor
{
    public static void Intercept( object target, Action onPropertyChangedAction, string propertyName)
    {
        onPropertyChangedAction();
    }
}

The parameters are as follows

  • target: the instance of the object that OnPropertyChanging is being fired on
  • onPropertyChangedAction: a delegate used to fire OnPropertyChanging
  • propertyName: the name of the property being notified

Example Usage : Executing OnPropertyChanging on the UI thread

Often properties will be changed on a different thread to the UI. This is particularly comment in Silverlight application. Unfortunately changing the UI, which occurs when a databound property changes, is not supported in Silverlight or WPF. The workaround is to "dispatch" the property changed event to the UI thread.

PropertyChangingNotificationInterceptor

public static class PropertyChangingNotificationInterceptor
{
    public static void Intercept(object target, Action onPropertyChangingAction, string propertyName)
    {
        Application.Current.Dispatcher.Invoke(onPropertyChangingAction);
    }
}

Your Class

public class Person : INotifyPropertyChanging
{
    public string Name { get; set; }

    public event PropertyChangingEventHandler PropertyChanging;
}

What Gets Compiled

public class Person : INotifyPropertyChanging
{
    private string name;

    public event PropertyChangingEventHandler PropertyChanging;


    public virtual void InnerOnPropertyChanging(string propertyName)
    {
        var propertyChanging = PropertyChanging;
        if (propertyChanging != null)
        {
            propertyChanging(this, new PropertyChangingEventArgs(propertyName));
        }
    }

    public virtual void OnPropertyChanging(string propertyName)
    {
        Action action = () => InnerOnPropertyChanging(propertyName);
        PropertyChangingNotificationInterceptor.Intercept(this, action, propertyName);
    }

    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            OnPropertyChanging("Name");
            name = value;
        }
    }

}

Property values

If you want to get access to the property values without reflection you can use a similar approach to what is described in [BeforeAfter]. To achieve this change the signature of PropertyChangingNotificationInterceptor.Intercept to be as follows.

public static class PropertyChangingNotificationInterceptor
{
    public static void Intercept(object target, Action onPropertyChangingAction, string propertyName, object before, object after)
    {
        onPropertyChangingAction();
    }
}

Where before and after with be the values of the property before and after it is set.

Implementing your own OnPropertyChanging

For classes that already implement OnPropertyChanging method then having a PropertyChangingNotificationInterceptor class will have no effect on those classes. If you want to dispatch event to the UI thread then you can do this yourself in OnPropertyChanging.

Clone this wiki locally