Validation. Hey! You’re Done! - Jesse Liberty - Silverlight Geek Page view counter

Validation. Hey! You’re Done!

 

Towards the end of my “What’s New In Silverlight 3” presentation for Tech Ed,  I discuss the (much anticipated) enhanced Data Validation in SL3.  Now, anyone who has been around the block a few times knows that there are a lot of different ways to handle data validation, and that each framework offers a different approach (not that long ago the approach was summed up as “hey, you’re a programmer, you want data validation, write some.”)

error1

error3

Plus Ca Change, plus c’est la meme chose

In October I wrote a blog entry about Data Validation in Silverlight 2.  It is interesting to look back at it now and realize that what has changed is not the use of the binding engine, setting the mode to two way, or even setting NotifyValidationError=true andValidationExceptions=true. All that was true back in October.

What has changed is that back in October, we wrote the code to manage everything about the validation – not only the business logic (which is to be expected and desired) but the entire UI for managing the error notification:


olderrorcode

From Hand Coded To Toolable Visual State


ValidationStates

The key innovation in Silverlight 3 is to tie error handling into the Visual State Management of the control. We are used to the fact that all the standard controls have two state groups: the CommonStates and the FocusStates. To these we now add three ValidationStates,

What is more, a number of input controls (TextBox, CheckBox, RadioButton, ListBox, ComboBox and soon PasswordBox) already have default storyboards for transitioning into these states (as you’ll see in just a moment

This means that right out of the box these controls know how to respond to invalid data, where the validity is determined by the object to which they are bound. Sweet.

Writing The Code

Let’s start simple, using the out-of-the-box capabilities, and then in a subsequent post I’ll look at how a little templating can give you much finer control over the interaction with the user.

To make this work you need the following:

  • A form with a way for the user to provide input (we’ll use a text box)
  • A data object to bind the input control  to
  • A user to enter incorrect data

Here is a picture of the form, displaying the error message that is caused by entering an invalid ISBN (one that has the right number of digits but where the checksum does not compute correctly):

checksumInvalid

We’ll support two other errors as well (not the right number of digits, and invalid values)

InvalidLength

invalidValues

Start With The Data

What I like most about this model is you start with the data, not the UI. You begin by designing your data object, and what validity checks you want.  I’ll post the code right after Tech-Ed, but I start with a Book class that implements INotifyPropertyChanged in the normal way. Then I added to the property for the ISBN my validation checking, throwing an exception if it is invalid in any way. The text I put in the exception is the text that shows up in the error message.  Here’s the ISBN10 property:

public string ISBN10
{
get
{
return isbn10;
}
set
{
if ( value.Length != 10 )
{
throw new ArgumentException( "Must be exactly 10 integers long" );
}

char[] isbnAsArray = value.ToCharArray();

foreach ( char c in isbnAsArray )
{
if ( ( !Char.IsNumber( c ) ) && c.ToString().ToUpper() != "X" )
{
throw new ArgumentException( "Must be numbers or letter X" );
}
}

int runningTotal = 0;
for ( int i = 0; i < 9; i++ )
{
int val = ( Convert.ToInt32( isbnAsArrayIdea.ToString() ) * ( 10 - i ) );
runningTotal += val;
}
int mod = runningTotal % 11;
int checkSum = 11 - mod;

int isbnCheckSum = -1;
if ( isbnAsArray[9].ToString().ToUpper() == "X" )
isbnCheckSum = 10;
else
isbnCheckSum = Convert.ToInt32( isbnAsArray[9].ToString() );

if ( isbnCheckSum != checkSum )
{
throw new ArgumentException( "Checksum is invalid!" );
}

isbn10 = value;
NotifyPropertyChanged( "ISBN10" );

}
}

[ Checksum computation from Wikipedia. ]

From Data To DataBinding

Once you’ve created your data object, you can build the UI around it, and bind the display objects to the properties of the data object. I decided to create the page in Blend, making it absurdly easy to lay out the rows and columns and to define the style for the prompt and for the data entry text box.

BlendValidation

I could have assigned the visual state, etc. inside Blend, but since I wasn’t changing anything, but rather just using what is already provided I saved this and clicked on Edit In Visual Studio. I then added the binding for the Title and Author by hand,

<TextBox x:Name="Title"
Grid.Column="1"
Grid.Row="1"
Text="{Binding Title}"
Style='{StaticResource Input}' />
<TextBox x:Name="Author"
Grid.Column="1"
Grid.Row="2"
Text="{Binding Author}"
Style='{StaticResource Input}' />

And followed that by adding the binding for the ISBN which required just a couple extra properties, but, you’ll notice, the same properties discussed in the October article and shown above,

<TextBox x:Name="ISBN10"
Grid.Column="1"
Grid.Row="3"
Style='{StaticResource Input}'>
<TextBox.Text>
<Binding Mode="TwoWay"
Path="ISBN10"
NotifyOnValidationError="True"
ValidatesOnExceptions="True" />
</TextBox.Text>
</TextBox>

That’s it! the rest just works.  No, really.

One Little Extra

Alright, if you want to get fancy; the text box doesn’t update and check the validity of its contents until you tab out (how else can it know when you’re done?). Cribbing from Karen Corby’s presentation at Mix I added a button to attach the UpdateSource() method of BindingExpression onto, and while I was at it, being amazingly lazy, I added a button that puts in the real ISBN for Death In Venice (one does get tired of typing the same thing while debugging!)

Here’s the Xaml,

<Button x:Name="FillButton"
Content="Fill Textbox With valid ISBN 10"
Width="200"
Height="25"
FontSize="14"
Grid.Column="0"
Grid.Row="4"
Margin="5"
HorizontalAlignment="Right" />

<Button x:Name="ValidateButton"
Content="Validate Now!"
Background="Green"
Width="120"
Height="25"
FontSize="14"
Grid.Column="1"
Grid.Row="4"
Margin="5"
HorizontalAlignment="Left" />

and here’s the code-behind for the buttons,

void ValidateButton_Click( object sender, RoutedEventArgs e )
{
// BindingExpression requires using System.Windows.Data
BindingExpression bindingExpression =
ISBN10.GetBindingExpression( TextBox.TextProperty );
bindingExpression.UpdateSource();
}

void FillButton_Click( object sender, RoutedEventArgs e )
{
ISBN10.Text = "0141181737";
}
womc900

This code was compiled with Silverlight 3 – Which is a beta product!  For more on this guarantee, please see this page.

Published Monday, May 04, 2009 12:39 AM by jesseliberty

Comments

# re: Validation. Hey! You’re Done!

Cool, Does the story change if I am using a Silverlight3 DataForm?

Monday, May 04, 2009 2:03 AM by Steve Strong

# Validation. Hey! You’re Done! - Jesse Liberty - Silverlight Geek

Thank you for submitting this cool story - Trackback from DotNetShoutout

Monday, May 04, 2009 2:24 AM by DotNetShoutout

# Validation. Hey! You&#39;re Done! - Jesse Liberty - Silverlight Geek

Pingback from  Validation. Hey! You&#39;re Done! - Jesse Liberty - Silverlight Geek

# Validation. Hey! You&#39;re Done! - Jesse Liberty - Silverlight Geek

Pingback from  Validation. Hey! You&#39;re Done! - Jesse Liberty - Silverlight Geek

# More Validation Fun - But Not Done Yet

URL : silverlight.net/.../archi... I was reading Jesse Liberty's Validation post

Monday, May 04, 2009 6:42 AM by Community Blogs

# re: Validation. Hey! You’re Done!

This is great!  One question, how would you internationalize this.  Should the data layer know about how the UI is showing it's text so the exception can have the correct text in it?

Monday, May 04, 2009 3:12 PM by chadyost

# re: Validation. Hey! You’re Done!

Keep up the good work. Question how would you validate a value to see if it exists in a database?

Monday, May 04, 2009 10:31 PM by bigred242

# Programming news: MicroFocus acquires Borland, Aleri integrates Coral8 engine with Windows HPC Server | Programming and Development | TechRepublic.com

Pingback from  Programming news: MicroFocus acquires Borland, Aleri integrates Coral8 engine with Windows HPC Server | Programming and Development | TechRepublic.com

# Life - Me, Myself, and We &raquo; links for 2009-05-18

Pingback from  Life - Me, Myself, and We  &raquo; links for 2009-05-18

Monday, May 18, 2009 4:01 PM by Life - Me, Myself, and We » links for 2009-05-18

# What’s New In Silverlight 3 - Validation

Data Validation is fully implemented in Silverlight 3, utilizing the object the input control is bound

Saturday, July 18, 2009 2:05 PM by Jesse Liberty - Silverlight Geek

# What’s New In Silverlight 3 - Validation

Data Validation is fully implemented in Silverlight 3, utilizing the object the input control is bound

Monday, July 20, 2009 1:46 PM by Microsoft Weblogs

# re: Validation. Hey! You’re Done!

at first it didnt work for me since i didnt study the last posts about data binding completely. perhaps its written somewhere there. also your comment "utilizing the object the input control is bound" wasnt that clear to me...

now i know that the datacontext has to be bound.

ok its clear to someone who knows how all the stuff works but i assumed something like its bound to the code behind class automatically.

Monday, October 05, 2009 6:11 PM by justmesaying