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)