Introduction

WPF is a fairly new technology (OK, it's been around a while), so it's still growing and new techniques and ideas are developing all the time. As developers, we are expected to provide users with usable systems. As part of a usable system, we must provide input validation of some sort. Now, WPF does come with a standard mechanism for this, but as you shall see, it's not perfect, and that it is limited in certain areas.

What this article will attempt to outline is a possible solution to the inbuilt WPF shortcomings. It does assume you know a little bit about WPF and validation in general, but it should cover most ideas in enough detail that WPF newbies should be OK.

What Does This Article Attempt to Solve

As I stated, this article will attempt to show you an alternative validation concept that fills the gaps with the standard WPF validation mechanism.

But what's so wrong with the standard WPF validation mechanism? Well, typically, the inbuilt WPF validation mechanism provides means of validating a single object. So it provides bounds checking for that object if you will. So how does this work? Well, although that's now the main push for this article, it is worth a quick mention...so here goes.

The Standard WPF Validation Works Likes This:

In the .NET 3.0 days, you would have typically done something like this:

The big problems that I personally have with all these standard methods are:

You can only validate the object that you are binding to. Now, that is OK in some cases, but my business has pretty complicated rules for data, that span across multiple objects. This is where it all falls down using the standard WPF validation techniques. I am totally unaware of how I could cross-validate a field using a value from another object using the standard mechanisms.

Some companies of mine included don't really gel with the idea of having business rules inside our business object; this seems to bloat the objects somehow. We prefer lean mean lite-weight business objects. Rocky Lhotka CSLA framework advocates the use of business objects holding their own rules, and he is a very, very smart guy, so maybe it is not all that bad. It is down to personal taste, I guess.

However, there is no denying that item 1 above just can not be solved by having each business object hold its own validation rules. I mean, how would you validate a business object if it needed to do so with some knowledge of another object. Even using some of the new WPFism Design Patterns such as MVVM, we may end up with a ViewModel holding a number of business objects that drive a single View. There will be a high probability that there may actually be some cross-business object validation required in these cases.

This led me to have a think about it a bit, and it led me to actually ditch what I had thought of as a good thing; so I ditched the use of the IDataErrorInfo interface all together. But why did I do that?

So What's Your Idea?

Well, I personally think that validation logic doesn't actually belong in the objects themselves. I decided to move those rules out of the business objects. So where could I do my validating? I have to do it somewhere, right? Right indeed, so what I decided to do was stick to using a couple of WPF goodies such as:

Model View View Model Design Pattern

INotifyPropertyChanged, for happy binding

And then I decided to do the following:

Remove all validation out of my business objects into a central validating object, which knew about all the relevant objects by having access to a ViewModel

The ViewModel would make itself known to the validator

The ViewModel would hold objects that drives the View

The View would bind to the ViewModel

The ViewModel would hold a list of all validation errors

A new set of controls were made (I have only done TextBox, but the idea applies to any control you choose) that when bound would accept a parameter, which indicated which list of business rules it was interested in seeing validation failures for

That is pretty much it. So how does this look in code?

Well, let's see an example app (this is the demo app attached, but you can change it to suit your actual needs):

Ok, So How Does it Work

Well, quite simply, it works as follows. The actual business objects (Person classes) simply have properties that notify bindings of changes via the INotifyPropertyChanged interface mechanism. There is a single ViewModel (Window1ViewModel) object per window (you may decide to have a number of View Models to govern your page, that is up to you), which holds a number of business objects (Person classes) that the View (Window1) needs to bind to. So basically, the View will bind directly to the ViewModel (this is the MVVM pattern). The ViewModel also holds a validator (Window1Validator) which is responsible for running all business logic for a given ViewModel. As such, the validator (Window1Validator) needs to know about the ViewModel (Window1ViewModel), so that it can examine the ViewModel's (Window1ViewModel) business objects (Person classes) values, that are currently driving the View (Window1).

So, what happens next is that the View (Window1) will at some stage have to validate its contents. For the demo, that moment occurs when a validate button is clicked, which will call a Validate() method inside the associated ViewModel (Window1ViewModel). When the ViewModel is asked to validate, it simply passes the call on to its internal validator (Window1Validator). As the internal ViewModel held validator knows about the ViewModel (Window1ViewModel), it is just a case of running through whatever business validation logic you want.

When you do run through the business validation logic, a ViewModel (Window1ViewModel) held ObservableCollection<ValidationFailure> is added to, where the Key property of the ValidationFailure key will be some unique name. This could typically be the name of the property you are validating, such as "Age". The beauty of this approach is that you have access to all the objects that drive the View, which allows cross object validation. This is something that the standard WPF validation framework just doesn't cater for (to the best of my knowledge).

So once we rattle through all the validation logic, we end up with a bunch of broken rules in the form of a ObservableCollection<ValidationFailure> within the ViewModel (Window1ViewModel), that can be used to bind to. As each ValidationFailure key will be some unique name, we can strip out only the ones that match a particular field on the View, which is done by using a ValueConverter, or choose to view all of the ObservableCollection<ValidationFailure> for the entire View.

Roughly, that is how it all works, so time for some code.

The Code Examples

So I guess it is time to start examining the code. Well, let's start with the business objects themselves. The demo uses the following business object:

Again, this class inherits from a base class that offers several useful things such as the INotifyPropertyChanged interface implementation. It can also be seen that this example ViewModel holds several business objects that will be used by the View to bind to. This ViewModel is then used to bind against in the View, where the DataContext of the View is set to be this ViewModel. Let us have a look at the View next.

///<summary>/// Demonstrates an alternative way fo validation across all objects within a
/// View, rather than using IDataErrorInfo which must be done on your actual
/// DomainObject and can only validate internal properties.
///</summary>publicpartialclass Window1 : Window
{
private Window1ViewModel window1ViewModel = new Window1ViewModel();
public Window1()
{
InitializeComponent();
this.DataContext = window1ViewModel;
}
}

As you can see, the View is using the Window1ViewModel ViewModel as its DataContext, which allows controls on the View to bind to the ViewModel directly. I am not going to bore you with all the XAML for the View, but will just show you a typical binding for one of the ViewModel held business objects.

So you can see that we have a specialised TextBox (TextBoxEx) which is being bound to the ValidationErrors property of the current DataContext of the View (which is really the Window1ViewModel ViewModel). It can also be seen that we are using a ValueConverter (ValidationErrorsLookupConverter) where we feed a parameter value into the ValueConverter.

To understand that mechanism, we need to first understand how the ValidationErrors property works within the Window1ViewModel ViewModel, so let us examine that now.

Basically, what happens is when a new ViewModel (Window1ViewModel) is constructed, it creates a new validator object (Window1Validator) which is used to perform all validation on the ViewModel (Window1ViewModel). The validator object (Window1Validator) simply runs through a chunk of really boring rules code, and appends a new ValidationFailure object to the list of ObservableCollection<ValidationFailure> held within the ViewModel (Window1ViewModel).

Let us examine the code for the validator object (Window1Validator); it is pretty dull stuff, but that is the nature of validation code.

The important part to note here is that the ViewModel (Window1ViewModel) holds a complete list of all the ValidationFailures that occurred, and that each ValidationFailure has a key that can be used to grab only those ValidationFailures that are related to a specific TextBox. Which is exactly what happens within the ValueConverter (ValidationErrorsLookupConverter) where we fed a parameter value into the ValueConverter, which is used to obtain only those ValidationFailures that pertain to the TextBox that has the correct key (value converter parameter value), which will be used to filter the list of all the ValidationFailures to only those that match the key (value converter parameter value).

Recall this binding for a single TextBoxEx within the XAML:

I am not going to bore you with all the XAML for the View, but will just show you a typical binding for one of the ViewModel held business objects.

The last step was in having a specialised TextBox (TextBoxEx) which knows how to show its own list of validation errors in a popup. Now, this is just what I chose to do, you may think up something different, but that is what I chose to do.

I should also point out that generally I am against creating specialised controls that inherit from System.Windows.Controls, as most extra behavior can be added via attached properties, but this just didn't seem to fit in this case, as I wanted the popup within the XAML to be triggered by mouse moves etc.

Josh Smith will more than likely say, oh you just do this, then that, and there you have it. I will just smile back at the man and go "That's nice to know, thanks Josh".

Since writing this article, a reader, "SE_GEEK", has proposed a new control which inherits from ContentControl instead of TextBox; you can read more about that approach using the forum link: GlobalWPFValidation.aspx?msg=2895494#xx2895494xx.

Anyway, here is the code for the specialised TextBox (TextBoxEx) which knows how to show its own list of ValidationFailures within a popup. I have only done a specialised TextBox (TextBoxEx) for the attached demo code, but you could apply the same idea to any of the standard controls. At work, we have actually done that with CheckBox/ComboBox and other controls, and it works very well.

And that is pretty much it. With this mechanism, we are able to perform pretty much any cross business object validation we like for the current View. And to prove that, here are a couple of screenshots:

Here is a Single pop for a single TextBoxEx object:

And here is what I get for all the errors for the current View:

That's it

That is all I have to say. I hope this article has helped you a little. If you liked it, could you please be kind enough to leave a vote or a message? Thanks.

Amendment

Since publishing this article, a colleague (Colin Eberhardt) has informed me that as of .NET 3.5 SP1, this is actually possible using the standard WPF mechanisms of BindingGroups. As .NET 3.5 SP1 is such a monster, I am not that surprised I missed this. Anyway, Colin has written an excellent post on this, and you can read all about it over at his blog. Here is a link: BindingGroups for Total View Validation.

Hi Sacha. I enjoyed your article very much. I think that to better embrace the spirit of MVVM, the purview of error messages belongs in the View, and not the validator in the ViewModel. This can be accomplished by having the validator return enumerations or classes, and then having a converter in the view convert them to error messages, which also lets it handle localization. I demonstrate this approach in Localization and Complex Validation in MVVM.

Ah I never tried it in a DataTemplate before that was not really my intention. I think for that to work you would need to dig into the generated items template, alas as this was not my intention, I have not looked into this, and I simply don't have the time right now.

Sorry to say.

Sacha Barber

Microsoft Visual C# MVP 2008/2009

Codeproject MVP 2008/2009

Your best friend is you.I'm my best friend too. We share the same views, and hardly ever argue

This is a reply to a "cold" article but you sent me here following our discussion in your Cinch article and I came here and yet again have a question...

Why is it you find it bettet to have validations performed in the ViewModel rather than in the object. Are validations not an integral part of the BO design-wise?What if you decide to use the object in a UI-less procedure (say - you take in data from excel?) - you would have to write the validations all over again. The same applies for server side - client side validations as we discussed.What am I missing here?

Good article of course (I expect nothing less from Sacha) but I don't believe that IDataErrorInfo should be used to Validate property data, just to report data errors.

I like using IDataErrorInfo since almost every WinForm (and now WPF) control uses it to report validation errors. But I move all data validation checking outside the object and just create code in the object to save and report errors via the IDataErrorInfo:

Hi!I like your article, it makes much more simple to use validation with WPF.I'm still exploring the WPF world and the MVVM pattern.I was experimenting a bit with it and figured out that i could create static validationclasses for my models for general (common) validation like:

No I think your idea works. At the end of the day, Validation is one of those topics where everyone has their own ideas, my idea is just one way. If you find it is better for you to do something slightly different, that is really cool.

And yeah you could still use IDataErrorInfo in conjunction with what I have proposed here, so the bounds checking could be in the business objects using the IDataErrorInfor idea or your idea, and then just do the cross domain checking somewhere else.

Like you say, it is all pretty flexable really.

Sacha Barber

Microsoft Visual C# MVP 2008

Codeproject MVP 2008

Your best friend is you.I'm my best friend too. We share the same views, and hardly ever argue

Hi Sacha, I enjoyed this article a lot, I am relatively new to WPF and I have found your articles to be a great asset in the learning process.

I know you mentioned you didn't like having to extend the TextBox class with TextBoxEx (and my inner software engineer didn't like it either) so as a test to myself I found a way around that.

I modified your code by creating a class called 'ValidatingContainer' ( I know its a bad class name, but I struggle at times to come up with good ones), which is a ContentControl. I pretty much then took all of your code for TextBoxEx and did a find replace for TextBoxEx to ValidatingContainer.

Here is the code in case you are interested (sorry this will be a verbose posting, if you prefer I can email you files I added/modified)

Then I modified the style in ControlBaseStyles.xaml again replacing all instances with TextBoxEx with ValidatingContainer. The only slightly tricky (for a noob like me anyways) part was replacing the scroll viewer in the style named "PART_ContentHost" with a "<contentpresenter />" and it works like a charm. I hope my attempt here is useful to you, or at least gives you an idea.

As I said before I am new at this, so if you have any suggestions to make what I did better I would love to hear about it. -David

I am binding whatever property on the content I want instead of text (in this case I wrap a TextBox and I am binding its text) ... which means it could be the text of a textbox, or a combobox ... or what have you. I didn't think of it before but this approach may yield something interesting if you nest multiple Validating containers (for example nest a panel in one, and then inside that panel have several validating containers each with a textbox. Then if you mouse over the individual boxes you get detailed validation messages, but if you mouse over the whole panel you get the whole collection.

Would probably have to change that so the popup isn't triggered by mouse-over (but mouse hover maybe) so you actually have a chance to mouse over the inner fields ...

It's funny how many people in the WPF community (myself included) have seem to hit the problem of complex businessvalidation at the same time. I've been working the last 3 weeks on my own solution.

I have been writing WPF data entry templates for medical records the last 4 months that require validation across entities. If entity A has this field then entity B requires this field, etc. The entities themselves have complex validation too. If field '1' in an entity has a value then field '2' requires a value, etc (in addition to the checks on if the field itself is valid). The number of entities on a view could change too since doctors could add new entities such as diagnostic tests to a "entity collection editor" that I created (this replaced the former WinFormdata grids that the doctors hated). So the number of entities on a View was dynamic.

My solution was to have any Control (mostly reusable UserControls which host the data entities) implement a IEntityValidator interface that I created. When validating before saving the objects through the data-service, my View class (I used a MVP pattern) would recursively walk through all DependencyObjects on the View (the derived medical record Views themselves would implement IEntityValidator itself if they needed to check for requirments that coupled entities) and call each IEntityValidator.Validate method that it found. If there where no errors this method would return NULL otherwise it would return a EntityValidationError object that stored the list of error messages, a reference to the Control, and a reference to the entity object. I collect all errors in a List<EntityValidationError> and then popup a dialog window very similar to the one that you created. Since I had a reference to the UI objects I could set their background to red or change their border.

Thanks, it's an honour to be up there with Josh. he is my like Idol or something like, he rocks.

TonyJ wrote:

implement a IEntityValidator interface

....

TonyJ wrote:

View class (I used a MVP pattern) would recursively walk through all DependencyObjects on the View

Before I started at this job, this is exactly what they done also using the VisualTreeHelper and using the MVP pattern and the Smart Client Software Factory....

It is all cool.

Tell me do you see a benifit in this I have outlined here. The reason I ask is that a couple of my WPF buddies have been doubtful it works, but I think it works just fine. Rocky (The business object guru) said somewhere, I see no problem with business objects being in an invalid state as long as they are not persisted to the database.

I think this and your approach allow for this just fine. To my mind as long as the state of the object can be classed "INVALID" all is ok.

Sacha Barber

Microsoft Visual C# MVP 2008

Codeproject MVP 2008

Your best friend is you.I'm my best friend too. We share the same views, and hardly ever argue

I see benefit in what you have done ... we just chose different ways to skin the same cat. I like your ideas and will study them further to see if I can somehow incorporate some of them in what I have done.

The motivation for what I did was that the data-service (developed by two other engineers on the team) already enforces all of the same validation rules via foreign key constraints and business logic. The data-service prevents invalid data from even reaching the database. We started off with no UI side data validation other than simple ValidationRules to enforce correct data in certain fields. The problem was the data-service gave back error messages that the doctors didn't know which control/field it applied to and the messages were not user friendly. I chose my method because it was the first idea that made sense that came to my head that fit into our solution. We were pretty far along in the project by the time we started getting feed back from product managers. I implemented an auto-save feature on the medical record templates too that just turns the entity usercontrols red if there is an error with no popups (just a tooltip will show explaining what is wrong) ... we can't have popup windows showing themselves as a user is typing (because the doctors are looking at medical records in a PDF viewer and not the template itself) and the auto-save thread kicks in. A dialog does popup if the user presses the "Save" button, however.

Since millions of developers read this site and there are so few advanced WPF articles here (besides what you, Josh and a handful of others post) do you find this helpful to your consulting career?

This reminds me of my own work recently, where i used the VAB (EntLib 4.1) that includes comprehensive extension points for validation, to write my custom cross business object validation system for an enterprise WPF app.

Yours is "super cool", as usual!

My 5 for you ... well... speaking in my favourite language... and topping it with a little lambda "espresso"...