INotifyPropertyChanged with PostSharp 1.5
If you are doing WPF development, most likely you are tired of writing property implementations that raise PropertyChanged event manually:
public class MainWindowViewModel : ViewModel { private string _message; public string Message { get { return _message; } set { _message = value; OnPropertyChanged("Message"); } } // ... }
PostSharp is a great tool to make such things simplier.
Let’s look at the specific ViewModel class that has a Message property that is bound to some UI element using XAML:
public class MainWindowViewModel : ViewModel { [RaisePropertyChanged] public string Message { get; set; } // ... }
Notice the RaisePropertyChanged attribute, which we’ll implement later.
Here’s our base ViewModel class that provides actual implementation of the INotifyPropertyChanged interface:
public class ViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged = delegate { }; public void OnPropertyChanged(string propertyName) { PropertyChanged(this,new PropertyChangedEventArgs(propertyName)); } };
Finally the PostSharp attribute:
[Serializable] // required by PostSharp public class RaisePropertyChangedAttribute : OnMethodBoundaryAspect { private string _propertyName; /// <summary> /// Executed at runtime, after the method. /// </summary> public override void OnExit(MethodExecutionEventArgs eventArgs) { ViewModel viewModel = (ViewModel)eventArgs.Instance; viewModel.OnPropertyChanged(_propertyName); } public override bool CompileTimeValidate(MethodBase method) { if (IsPropertySetter(method)) { _propertyName = GetPropertyName(method); return true; } return false; } private static string GetPropertyName(MethodBase method) { return method.Name.Replace"set_", ""); } private static bool IsPropertySetter(MethodBase method) { return method.Name.StartsWith("set_"); } };
Note that we are validating if the method is in fact a property only during compilation time using CompileTimeValidate method.
During compile time appropriate invocations of OnPropertyChanged method will be injected after every set operation applied to the Message property.
September 15th, 2013 at 19:11
Does the PostSharp allow to put such attribute on class definition instead of property?
It would be nice to have this attribute on base ViewModel and nothing on properties (less work and convention over configuration at the same time).
September 15th, 2013 at 21:04
Yes, you can put the attribute on the class level.
In such case all class properties will raise appropriate PropertyChanged events.
Although I think that in PostSharp 1.5 it can not be the base class – PostSharp attributes are not inherited.
February 16th, 2014 at 21:48
[…] One that I particularly like is by using PostSharp to implement INotifyPropertyChanged. […]
May 24th, 2015 at 08:48
[…] can use PostSharp for that, you should at least use lambda expressions instead of […]
August 22nd, 2015 at 05:37
Thnx for the example… seen other examples out there much more complicated to start out with. One thing I’d like to note is that you could use “dynamic instance = args.Instance;” to expand the use to anything that has an OnPropertyChanged(string); method. For example I have objects that need change notification.