We recently started to build a desktop application with WPF and MVVM.

When we had the need for a validation framework for our view inputs, I started to look on internet to find "de facto" approach for MVVM and WPF in general. There are lots of look-alike methods for validation.

For validation I commonly saw three approaches:

  • Validation Rules on views
  • Hand coded validation on ViewModel setters
  • Using some validation framework attributes (mostly System.ComponentModel.DataAnnotations) on binded Model properties or ViewModel properties.

For validation error user notification, people complain about how WPF lacks old Windows Forms built in Error Provider support and invent their custom ones with IDataErrorInfo interface.

The problems with the implementations I saw so far was they were like toy examples or have overly complex implementations. One implementation outstands for me from the rest.

In Mariano Omar Rodriguez's validation approach, ViewModel decorates its properties with Data Annotations for validation, and to check these attributes are really valid, ViewModel uses some reflection and Linq Expressions. To show errors ViewModel also implements IDataErrorInfo interface. While Mariano's approach seemed a little complex, if I could carry complexity (IDataErrorInfo implementation and reflection methods/properties) to a ViewModelBase class, adding new properties and validations would become fairly easy.

I modified Mariano's code with generics to move all those overhead to a base class. Two things I couldn't carry without friction were IDataErrorInfo's members this[string] indexer and Error property, because these properties send "this" instances to reflective methods for gathering IsValid infos from Data Annotation attributes. I was stuck there for a good solution. My collegue Niyazi came with a solution which suggests we should declare a T type property in ViewModelBase, and use T property instead of "this" in ViewModelBase and actual ViewModels which inherit from ViewModelBase should assign their selves to this generic typed property in their constructors. We were not totally ok with this yet another overhead for the ViewModel. But it's less crappy or less code from other solutions out there. So we settled for this solution.

You can grab the solution attached below. Please feel free to comment on this solution's possible drawbacks.

Samples.Validation.BerkesVariant.rar (83.76 KB)

From the author of The Reciprocality Project white papers:

"Reciprocality is a private project to better understand the nature of the stresses and challenges facing the
software industry at the moment, particularly in respect of deep cultural issues in the model of the nature of
work. The intention is to be able to assist organisations to create conditions where they can maximise their
ability to attract, retain and get the best from able staff, while ensuring that younger staff are provided with
the conceptual and technical mentoring necessary to develop into aware and effective creative engineers.

The project is evaluating 10 years teaching experience in a very broad social and cultural context, and
appears to be generating interesting results. It would seem that the way that software engineering is
perceived in society at large can tell us much about difficulties society will face as the economy becomes
more clearly dominated by Information Age issues."

- Alan Geoffrey Carter

I downloaded the whole project site in PDF and checked out some of the articles. Though it may be dated old, I think it contains some valuable information.

A while (or may be a year ago), I blogged about the White Screen of Darn. It came with the Visual Studio 2005 designer, and occurs when for a reason designer couldn't render (generally referenced 3rd party) UI components.

And, it happens again.

With the new Visual Studio 2008 interface also we have a new WSoD error screen :).

The problem shows in a form, when an assembly of a 3rd party UI component directly or indirecly referenced multiple times. As the problematic error message will be like "type Asy1.TypeA couldn't be cast to Asy1.TypeA", this shows us, VS designer wrongly assumes same types as different types.

And here is the resolution: Clean the project, and Build it again.

Then, VS corrects its mistake, and shows designer without errror. ;)