MVVM Validation and Type Checking

This post is based on Present.Validation a part of the Present project at codeplex.

ScreenShot

Present.Validation is an implementation of IDataErrorInfo for MVVM which uses a pluggable contributor pattern to provide validation. It currently has a single contributor for use with System.ComponentModel.DataAnnotations. Validation can then be acheived by decorating the ViewModel properties with attributes

 [Range(0, 120, ErrorMessage = "Age must be between 0 and 120")]
public int Age 
 <StackPanel>
        <v:BrokenBindingNotifier PropertiesWithBrokenBindings="{Binding Validator.BrokenBindings}" />
        <Controls:Form Padding="20">
            <TextBox Controls:FormItem.LabelContent="_Firstname" Text="{v:ValidatedBinding FirstName}" />
            <TextBox Controls:FormItem.LabelContent="_Lastname" Text="{v:ValidatedBinding LastName}" />
            <TextBox Controls:FormItem.LabelContent="_Age" Text="{v:ValidatedBinding Age, TargetNullValue={x:Static System:String.Empty}}" />
        </Controls:Form>
        <Button Content="Save" Command="{Binding SaveCommand}" Width="50"/>
    </StackPanel>

There are plenty examples of implementing IDataErrorInfo on the web, but they tend to ignore broken bindings. Broken Bindings occur for a number of reasons such as the binding source can’t be found or the Path is invalid. They also occur when the input value can’t be coerced back to the data type of the source.

For example if someone tries to enter Twelve into a text box bound to the int Age property the binding will break; leaving the value of Age unset and the ViewModel unaware of the error.

Present.Validation tackles this via a binding notifier which binds broken bindings to the a validator. (Line 2 of the Xaml). It also uses a custom binding ValidatedBinding which just sets all the needed error checking properties to true.

Gotcha: Nullable Types

Watch out when using nullable types that you set the TargetNullValue as for the Age binding. An empty textbox is set to String.Empty which isn’t compatible with int?. So we need to tell WPF that String.Empty is equal to Null.

Advertisements

5 thoughts on “MVVM Validation and Type Checking

  1. weitzhandler says:

    Is there a way to achieve the above with when binding to entities (not MVVM, just direct binding to entities) that are generated by edm designer?

  2. adammills says:

    As far as I known, IDataErrorInfo has to be on the bound object. So you would need to bind the BrokenBindingNotifier to a collection on your entity, implment IDataErrorInfo and check the brokenbinding collection for errors when validating a property or entity as a whole. You could acheive this via decorating your entities, interception or just using a base class or partial classes.
    If you only care about broken bindings you could bind the BrokenBindingNotifier to a collection on a static object along with the entity in question…. adding view models would be easier 🙂

  3. weitzhandler says:

    Thanks for your response.

    I have another question.
    You probably got to know the ValidationContext class.
    I don’t find a way to initialize it in WPF, as I don’t know what should be the appropriate value for the serviceProvider parameter.

  4. adammills says:

    serviceProvider parameter is optional, if you don’t have a value or need it in the Context, you can pass null.

    I will look into supporting ValidationContext for use with CustomValidations that are depedentent on more than one property.

  5. weitzhandler says:

    I was wrong. it accepts null.
    Thanks.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: