ObservableObject: More goodness
I’ve been working my way through Karl Shiffett’s MVVM in a box training module. He has a neat little helper for the ObservableObject that adds a check to make sure you’ve wired everything up when using string-based property changed handlers.
Here is the new method:
/// <summary> /// Warns the developer if this Object does not have a public property with /// the specified name. This method does not exist in a Release build. /// </summary> [Conditional("DEBUG")] [DebuggerStepThrough] public void VerifyPropertyName(String propertyName) { // verify that the property name matches a real, // public, instance property on this Object. if ( TypeDescriptor.GetProperties(this)[propertyName] == null ) Debug.Fail("Invalid property name: " + propertyName); }
Here’s the Karl version of the entire class:
using System; using System.ComponentModel; using System.Diagnostics; using System.Linq.Expressions; //Event Design: http://msdn.microsoft.com/en-us/library/ms229011.aspx namespace XamDockManager.Common.Infrastructure { [Serializable] public abstract class ObservableObject : INotifyPropertyChanged { [field: NonSerialized] public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(String propertyName) { VerifyPropertyName(propertyName); OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } protected void OnPropertyChanged<T>(Expression<Func<T>> propertyExpresssion) { var propertyName = PropertySupport.ExtractPropertyName(propertyExpresssion); OnPropertyChanged(propertyName); } protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) { var handler = PropertyChanged; if ( handler != null ) { handler(this, e); } } /// <summary> /// Warns the developer if this Object does not have a public property with /// the specified name. This method does not exist in a Release build. /// </summary> [Conditional("DEBUG")] [DebuggerStepThrough] public void VerifyPropertyName(String propertyName) { // verify that the property name matches a real, // public, instance property on this Object. if ( TypeDescriptor.GetProperties(this)[propertyName] == null ) { Debug.Fail("Invalid property name: " + propertyName); } } } }
You might notice, there another external requirement, PropertySupport.
Here is that class as well:
public static class PropertySupport { public static String ExtractPropertyName<T>(Expression<Func<T>> propertyExpresssion) { if ( propertyExpresssion == null ) { throw new ArgumentNullException("propertyExpresssion"); } var memberExpression = propertyExpresssion.Body as MemberExpression; if ( memberExpression == null ) { throw new ArgumentException("The expression is not a member access expression.", "propertyExpresssion"); } var property = memberExpression.Member as PropertyInfo; if ( property == null ) { throw new ArgumentException("The member access expression does not access a property.", "propertyExpresssion"); } var getMethod = property.GetGetMethod(true); if ( getMethod.IsStatic ) { throw new ArgumentException("The referenced property is a static property.", "propertyExpresssion"); } return memberExpression.Member.Name; } }
If you’d like more info on MVVM for WPF, check out Karl’s In the Box – MVVM Training for VS 2010. You can get it for free.
http://karlshifflett.wordpress.com/2010/11/07/in-the-box-ndash-mvvm-training/
http://visualstudiogallery.msdn.microsoft.com/3ab5f02f-0c54-453c-b437-8e8d57eb9942?SRC=VSIDE
