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