Note: I rewrote this article on 12/29/2008 after speaking with my great friend and MVVM Master Josh Smith. I changed the ViewBase class to call a method on the ViewModelBase class instead of my original method of communicating from the View to the ViewModel using an ICommand. This is a cleaner and simpler solution. Originally I was trying to have a very decoupled solution. In my zeal to be pure, I overlooked the obvious and simpler approach.
The purpose of this article is to explain the necessity for monitoring binding exceptions caught in the UI that he data model would not be aware of. This material while explained in the context of M-V-VM, still applies to all WPF business applications.
The Problem
A TextBox in the View is bound to an integer property on the Model. That integer property has an associated IDataErrorInfo validation rule that requires that the property value be between 0 and 100.
If the user enters a value less than 0 or greater than 100, the Model will report an error that the binding pipeline will pickup and if the TextBox has a Validation.ErrorTemplate, will display some error message to the user.
Now the user enters 5b and tabs to the next field. Since 5b is not an integer, the binding pipeline will get an exception when attempting to set the property value on the Model since there is a type mismatch.
Now the TextBox.Text property on the View is 5b, the Model does not know that the View has an invalid value and if the Model’s current value is within the limits of any applied validation rules, the Model thinks it’s valid.
So you can see that under these circumstances there is a disconnect between the View and Model. It is this disconnect that I would like to address and provide a solution for.
Other Solutions I Considered
Purchase or author UI controls that do not allow invalid input. It is very easy to author a Numeric only TextBox in WPF. However, when you get to the Date TextBox, I think things get a little more complex and can end up with the same disconnect I explained above.
I’ve never liked masked input controls and users really don’t like them either. Besides, why can’t my Date TextBox work like the Outlook 2007 Date Input Control? Play around with Outlook’s, you’ll be surprised what you can enter and it just figures it out for you. For example, gives these a try: mon, fri, 3, 24. Also I want to bring back the ” + “, ” – ” and ” . ” keys for date entry.
Fancy control aside, it’s possible for a control like this to have invalid input that does not translate to a date and you end up with the same disconnect; View is invalid and the Model is valid.
As a person who writes lots of blog and Code Project articles, I can’t use a 3rd party control because developers would need to purchase the 3rd party control license in order to compile my projects on their systems. So that is a non-starter. I also want readers to be able to take my code and use it at their work if they so desired. Not taking a dependency on a 3rd party solution makes this much simpler for readers and me too.
Josh Smith has also come up with a very good solution that you can read in this blog post, Using a ViewModel to Provide Meaningful Validation Error Messages. I actually really like Josh’s solution as it provides a great solution including reformatting and data type conversion error messages. My only push back was having to abstract all the properties of the Model on the ViewModel. I have run into some scenarios were doing this has its own side effects that I didn’t want to have to code around.
This is also the beauty of M-V-VM. While the pattern has some specific layers and components, implementation details can differ, sometimes a good bit but yield the same solid results. I would encourage all WPF LOB developers to look at many different M-V-VM implementations and draw your own conclusions. I came to mine after spending 3 weeks memory profiling many M-V-VM applications with different implementations of the M-V-VM pattern. The patterns shared here, use the minimum amount of resources and do not have memory leak problems.
My Requirements
- Solution must be simple
- Solution must be reusable and easy to implement in many applications
- Solution must be rock solid and impossible for the user to get into an invalid or disconnected state as described above
- Solution must not require that controls on Views implement anything outside of the normal Data Binding properties
- Solution must provide data for an error listing in the View when the programmer needs it
- Solution must provide a simple technique for the ViewModel to know if the View and Model are valid for the purposes of View notification and Save Command enabling and disabling
Solution Architecture
The CustomerViewModel exposes the Customer Model as a property. You will discover that this entire solution is contained in two base classes, ViewModelBase and ViewBase. ViewModels and Views that derive from these classes won’t have to deal with this code at all. The solution just works. At Microsoft we say, “IJW.” (it just works)
During the CustomerViewModel lifetime, if the Customer objects needs to be reloaded, for example after a record is inserted or updated to the database, a re-read of the record in the database is required. After the record is reloaded, the CustomerViewModel can raise the PropertyChanged event for the Customer property and the View will automatically refresh itself. Implementing M-V-VM in this fashion makes for a clean approach that does not require the reloading of the View or ViewModel when the data changes, just the reloading of the Model in necessary.
The ViewModelBase class exposes three methods for working with data binding exceptions in the UI, AddUIValidationError, RemoveUIValidationError and ClearUIValidationErrors. The first two are public methods called by the below ViewBase.ExceptionValidationErrorHandler. The ClearUIValidationErrors is a protected method that the deriving ViewModel can call as required; for example when the Model exposed by the ViewModel is reloaded and the UIValidationErrors need to be cleared.
The UIValidationErrorCount property returns the number of UIValidationErrors. Use this property when checking for the presence of UIValidationErrors.
The UIValidationErrorUserMessages property is what the View data binds to when displaying a list of UIValidationErrors to the user. It returns one string with the property name and message, “has invalid entry” for each UIValidationError.
The UIValidationErrorFullMessages property is for demonstration purposes for this application only. Please remove this from any other application as it serves no purpose other than for this demo application.
When the user enters a value in the UI that causes an exception to be thrown by the data binding pipeline, the ExceptionValidationErrorHandler gets the exception. The ExceptionValidationErrorHandler actually gets called when the exception is initially throw and when the exception is cleared. Getting notification of exceptions being added and removed makes tracking these very simple. As stated above the ExceptionValidationErrorHandler calls either the ViewModelBase.AddUIValidationError or ViewModelBase.RemoveUIValidationError method when an exception is added or removed.
UIValidationError Sequence Diagram
Thank Josh Smith for the great suggestion to put this complex sequence of events in a Sequence Diagram.
In addition to the UIValidationErrorUserMessages property the UIValidationErrorCount property has property changed notification that the UI can data bind to.
While these seems a little complex, application View’s and ViewModels simply need to derive from these or similar classes to get the functionality for free.
Application
The test bench application allows has two sections. The top Customer section is the form for data entry. The UI and ViewModel Errors section displays UI Validation Exceptions and validation rule violations from the Model.
The Full Name field is a required entry from 1 to 30 characters long.
The Satisfaction Level field has a validation rule on the model requiring values to be from 0 to 100.
The red ” * ” indicate either a validation rule violation or that an exception was thrown when assigning a value to the Model property.
The Save button will only be enabled when the View and Model are both valid and without exceptions.
In the above image you can see that the Satisfaction Level is invalid. It’s not between 0 and 100. This is an IDataErrorInfo validation error. This is an example of a normal data entry validation rule violation and technique for displaying the condition to the user.
The Retired field, Nullable(Of Date) has an exception. “a11-12″ is not a valid date. The Model knows nothing about the invalid Retired TextBox, but since the ViewModel as been informed of the invalid TextBox.Text property, the ViewModel will not allow the user to save any data until the exceptions have all been corrected and the Model validation rules all pass.
I’m showing both the UIValidationErrorUserMessages and UIValidationErrorFullMessages properties. Notice how the UIValidationErrorUserMessages displays a user friendly version of the UIValidationError.
Future Usage
In future MVVM example applications, I’ll demonstrate using these classes in a real world application. For now, understanding that these conditions can exist is very important and that we need to handle them in our applications.
Video

This video link requires Microsoft Silverlight 1.0 or 2.0. If you do not have it, you will be prompted to install it when you click one of the links. After the short installation is completed, close the browser window that you did the install in and re-click the video you want to watch. You can also download it here. Windows XP or Vista required.
Download
After downloading the below file, you must rename the file from .DOC to .ZIP. This is a requirement of WordPress.com
Updated 12/28/2008 Download Source (26KB)
Hope you have a great day!
Just a grain of sand on the worlds beaches.




Karl, I stumbled across this post while searching for ways to handle data binding errors. This post really helped me a lot! I compared your solution to Josh Smith’s solution that you mentioned and fell on your way because it fit my situation a little better. I combined your ideas here with a great post by Paul Stovell on CodeProject (http://www.codeproject.com/KB/cs/DelegateBusinessObjects.aspx) to create a rules engine that is centralized and works very well in my library application I’m writing. Thanks a lot for this post, it expanded my knowledge of data binding and helped me solve my last nagging data binding issue. Keep up the great work!
Thank you very much for the nice complement. Glad the information was of assistance.
Cheers,
Karl
MVVM is great for separation of concerns. Karl you did a great job in explaining it. Here is another way of attaching a view to the view-model. just sharing another perspective to the viewers
– Shams (http://geekscafe.net)
<!–
–>
I think the XAML code was truncated… sorry! I dont know how to post it. – Shams
Yes there are many ways to accomplish similar tasks in .NET.
The best way to share information with users is to start a blog. Go for it.
Cheers,
Karl
Hi Karl the above mentioned post is very nice.
I am having some problem in understanding the source code as it is written in vb and i am not very good in the same.
If you Can please post the same source code in C# then it would be of gr8 help.
Thanks in advance.
Regards,
Samar
The source code in C# can be found here: http://www.cookingwithxaml.com/content/ChicagoLob/demos.zip
Unzip the file and navigate to this folder: demos\11.DataValidationinMVVM\MVVM Lab\CSharp\Solution
That is a C# version of the code.
Cheers,
Karl
Thanks for the great article Karl! I have a quick question for you. I am using your C# code along with Prism. Specifically I am using Prism’s DelegateCommand instead of your RelayCommand. For some reason, when validations fail in my application the Save button is not disabled. I put a breakpoint in my CanExecute() method and it is not hit after changing a field (even though PropertyChanged events are generated). In your sample app this method is being called almost every second. What might be the difference?
Thanks,
Naresh
Naresh,
The Prism DelegateCommand does not subscribe to CommandManager.RequerySuggested, which is why I don’t use it. DelegateCommand leaves it up to the developer for calling CanExecute.
RelayCommand subscribes to CommandManager.RequerySuggested if you pass the Predicate in the ctor. For WPF, I always use RelayCommand so I get this behavior for free.
Cheers,
Karl
Thanks. Exactly what I was looking for.
[...] like a lot of additional work. I additionally began looking into Karl Shifflett's implementation here, but I can't seem to capture the routed event I would anticipate when putting this code into the [...]
[...] article describes a solution which is much easier to implement in that most of the code is contained in two [...]
It’s a very nice implementation! But is there something like this for silverlight?
Yes, you can implement this in Silverlight too. A few things are different but not a big deal.
Karl
Hello,
Thank you for this great article !
I think validation can be the most difficult and less documented thing about WPF/MVVM.
Jonathan ANTOINE
http://blog.lexique-du-net.com
http://wpf-france.fr
Hai,
Thanks for your great article…
here i have one clarification..
i want to allow empty value also in Textbox… my TextBox is binding with Openingbalance Property..
openingbalance datatype is Decimal… this field also allows nullable… here suppose i entered value 5.50 then clear all value after changing focus.. that time also Exception return…
how to solve this?
could you tell me some ideas?
Read this blog post: http://karlshifflett.wordpress.com/2008/12/16/using-wpf-binding-stringformat-property-with-nullable-types/
What you need is: TargetNullValue
Cheers,
Karl
Hello,
Thanks for your nice article…. suppose if i allow null to satisfication level ..after enter some values in this textbox finally clear all values in Textbox then press tab(that means lost focus) that time also exception throws…
how to solve this problem?
could you tell me some ideas?
thank you….
I don’t understand your scenario.
If you are binding to a nullable fields and are also using TargetNullValue, you should not get a type cast exception.
Karl
Hi,
k . i will explain in detail.
i am binding nullable decimal only….
first enter value like “siva” after clear all value in Textbox(That time value will empty)..
after press tab still its error…
can u suggest me?
do you have TargetNullValue set? If so, what is it set to?
Karl
here
private decimal? FormCost
public decimal? FormCost
{
get { return _formCost; }
set { _formCost = value; }
}
i didn’t set any TargetNull value ..
first edit textbox(that is enter some character suddenly clear all value then focus changed)
that time FormCost value “”. so i am still getting error..
here i want allow null also?
that is the problem???
Please read this blog post: http://karlshifflett.wordpress.com/2008/12/16/using-wpf-binding-stringformat-property-with-nullable-types/
What you need is: TargetNullValue
Its fully explained.
Karl
Hi Karl,
I know this is somewhat an old post, but it is undoubtedly a great one. There are very few solutions around providing a way to couple the validation to the view-model, so this one is of great value. Josh Smith’s solution is easy to implement and keep track of everything, but it makes me uncomfortable to have all my properties exposed as strings. Kinds of makes no sense if you think of a unit testing perspective, for example – you’d never be able to benefit on strong typing when testing the view model.
However, Josh’s solution has a definitive plus: you don’t need to work with value (or type) converters on the XAML side. And that is something I don’t see how your solution can cope with.
What if I want to bind my TextBox to an IPAddress property? Since IPAddress is not provided with a TypeConverter out-of-box, you have two alternatives: either writing an IValueConverter or writing a custom TypeConverter.
The IValueConverter.ConvertBack() method which is responsible for converting the string in the TextBox to an IPAddress instance cannot throw exceptions as documented in the Remarks section of http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.convertback(v=VS.90).aspx. That said, it should return a DependencyProperty.UnsetValue instead, which then leads to the fact that the setter of my IPAddress property is never called, hence leaving the validation method in the IDataErrorInfo call to be executed in the previous value of my IPAddress property, which possibly is the valid (considering you loaded it from the model, for example).
Implementing a custom TypeConverter is not much different than that. The good point is that you can throw an exception in its ConvertTo() method, which can be caught in the UI if your Binding.ValidatesOnExceptions is set to true. But then, the setter of the property is not called again, and you run into the same scenario when using IValueConverter.
So basically the idea is: how can the view-model know it is not in a valid state anymore, if its properties were not set?
Sorry for the lengthy email, but I guess that is something worth a thought
Any ideas? Thanks in advance!
(By the way, I’m using .NET 3.5)
My Ocean framework has property validators on the model that determines if the value is valid, so no type converters required. In the case of an IP address, the property would be a string and the validator would ensure the user input matches the required rule. I try to keep my code as simple as possible.
Best,
Karl
Hello Karl, Happy Holidays to you
Quick question;
I have a View with some TextBoxes bound to custom validation rules.
I have a Button on my View bound to a SaveCommand.
I’d like my SaveCommand’s CanExecute (CanSave) to only return true if no validation errors exist within my View.
Since my View is the one binding to validation rules, my ViewModel has no idea if any exist.
Is there a simple way to tap into this knowledge that my View has? I’d rather not write a trigger vs every TextBox on my View, and would rather see if I can just add validation errors to a collection somewhere that my ViewModel could bind to perhaps.
(I’ve also posted this question at http://social.msdn.microsoft.com/Forums/en/wpf/thread/6e464e8f-a7a0-4655-8647-7bf154b1e136 , but it seemed related to your post here.
Thanks,
-Mario