Validating Properties in Silverlight Classes
Silverlight classes rely on the INotifyPropertyChanged interface and associated PropertyChanged event it contains to ensure that data binding stays up-to-date in an application. It’s a great feature because you don’t have to worry about ensuring that changes to object properties are propagated back to controls….Silverlight handles refreshing control values for you automatically as long as the class that’s being data bound implements INotifyPropertyChanged and property set blocks raise the event. I use a fairly standard pattern for defining my properties and raising property changed events (there are several options for doing this…see a nice list here). Here’s an example of a property:
public Job CurrentJob { get { return _CurrentJob; } set { if (value != _CurrentJob) { _CurrentJob = value; OnPropertyChanged("CurrentJob"); } } }
The problem is that I tend to change property names from time to time within an application and use the Visual Studio refactor feature to do it. This works great for changing the property name or field name but doesn’t change the quoted value passed to OnPropertyChanged. I’ve run into a few issues where I missed renaming the string value and decided that I needed to be more proactive with validating the value. I ended up going with the following validation code after looking at a few options:
protected void OnPropertyChanged(string propertyName) { CheckPropertyExists(propertyName); if (this.PropertyChanged != null) { this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } [Conditional("DEBUG")] private void CheckPropertyExists(string propertyName) { Type type = this.GetType(); if (type.GetProperty(propertyName) == null) { string errorMessage = string.Format("Invalid property found: {0} in {1}", propertyName, type.FullName); Debug.Assert(false, errorMessage); } }
Originally I used #if..#endif statements to conditionally add or take out the CheckPropertyExists method until I came across a nice post by Josh Smith where he used the Conditional attribute in a WPF application. If you’re new to it, the compiler will leave CheckPropertyExists in the compiled code if you’re in debug mode. If you switch to release mode it’ll take it out which is good since at that point you wouldn’t want to slow down the application with the reflection statements.
With the CheckPropertyExists method in place I now have an easy way to know if I missed renaming a property value that’s passed to OnPropertyChanged which saves a few headaches. I put the code in my ViewModelBase class so I only have to write it once and have it available for just about everything I do in Silverlight. Here’s the message that I get if there’s a problem:
Update: The same day I posted this I ran into a mis-named property. The assert message popped up and I fixed it within a matter of seconds instead of searching through the code for minutes (or longer) to locate the problem.
For more information about onsite, online and video training, mentoring and consulting solutions for .NET, SharePoint or Silverlight please visit http://www.thewahlingroup.com/.