-
-
Notifications
You must be signed in to change notification settings - Fork 229
NotificationInterception
Sometimes it is helpful to be able to intercept call to OnPropertyChanged. For example
- Logging all property sets
- Performing some action before or after OnPropertyChanged
- Choose to not fire OnPropertyChanged under certain circumstances
- Executing OnPropertyChanged on the UI thread
All the points above can be achieved by having a static class named PropertyChangedNotificationInterceptor
in your assembly. The class should look as follows
public static class PropertyChangedNotificationInterceptor
{
public static void Intercept( object target, Action onPropertyChangedAction, string propertyName)
{
onPropertyChangedAction();
}
}
The parameters are as follows
-
target
: the instance of the object that OnPropertyChanged is being fired on -
onPropertyChangedAction
: a delegate used to fire OnPropertyChanged -
propertyName
: the name of the property being notified
Often properties will be changed on a different thread to the UI. This is particularly common in Silverlight applications. 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.
public static class PropertyChangedNotificationInterceptor
{
public static void Intercept(object target, Action onPropertyChangedAction, string propertyName)
{
Application.Current.Dispatcher.Invoke(onPropertyChangedAction);
}
}
public class Person : INotifyPropertyChanged
{
public string Name { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
public class Person : INotifyPropertyChanged
{
private string name;
public event PropertyChangedEventHandler PropertyChanged;
public virtual void InnerOnPropertyChanged(string propertyName)
{
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public virtual void OnPropertyChanged(string propertyName)
{
Action action = () => InnerOnPropertyChanged(propertyName);
PropertyChangedNotificationInterceptor.Intercept(this, action, propertyName);
}
public string Name
{
get
{
return name;
}
set
{
name = value;
OnPropertyChanged("Name");
}
}
}
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 PropertyChangedNotificationInterceptor.Intercept
to be as follows.
public static class PropertyChangedNotificationInterceptor
{
public static void Intercept(object target, Action onPropertyChangedAction,
string propertyName, object before, object after)
{
onPropertyChangedAction();
}
}
Where before
and after
with be the values of the property before and after it is set.
For classes that already implement OnPropertyChanged
method then having a PropertyChangedNotificationInterceptor
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 OnPropertyChanged
.