Geeks With Blogs
Peter Tweed Exploring and explaining the mysteries of .NET

It’s impossible to have a typical forms over data business application without handling validation in the UI.

3 has excellent simple to use support for implementing validation in your code.  This post will show a simple scenario to implement data validation.  The code for this post can be found here.

 

Steps:

1.    Create a Silverlight application.

2.    Add a class called Person and add the following code to the Person class:

 

        private string firstName;

        private string lastName;

        private string email;

 

        public string FirstName

        {

            get { return firstName; }

            set

            {

                if (string.IsNullOrEmpty(value))

                    throw new ArgumentException("First name in required.");

                firstName = value;

            }

        }

 

        public string LastName

        {

            get { return lastName; }

            set

            {

                if (string.IsNullOrEmpty(value))

                    throw new ArgumentException("Last name in required.");

                lastName = value;

            }

        }

 

        public string Email

        {

            get { return email; }

            set

            {

                System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(@"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?");

                if (!r.IsMatch(value))

                    throw new ArgumentException("A valid email is required.");

                email = value;

            }

        }

 

Note that this class has 3 properties – FirstName, LastName and Email.  Validation is carried out in the setter of each property to determine if a valid value is supplied.  If validation fails for a property an exception (in this case ArgumentException) is thrown.  This is the mechanism to tell Silverlight that something bad happened in setting the value of an object.

 

3.    Add the following XAML to the LayoutRoot Grid in the MainPage.xaml file:

 

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="50"></ColumnDefinition>

            <ColumnDefinition Width="100"></ColumnDefinition>

            <ColumnDefinition Width="100"></ColumnDefinition>

            <ColumnDefinition Width="50"></ColumnDefinition>

        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>

            <RowDefinition Height="50"></RowDefinition>

            <RowDefinition Height="25"></RowDefinition>

            <RowDefinition Height="25"></RowDefinition>

            <RowDefinition Height="25"></RowDefinition>

            <RowDefinition Height="25"></RowDefinition>

            <RowDefinition Height="100"></RowDefinition>

        </Grid.RowDefinitions>

        <TextBlock Text="First Name:" Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" ></TextBlock>

        <TextBlock Text="Last Name:" Grid.Column="1" Grid.Row="2" VerticalAlignment="Center" ></TextBlock>

        <TextBlock Text="Email:" Grid.Column="1" Grid.Row="3" VerticalAlignment="Center" ></TextBlock>

        <TextBox x:Name="FirstNameTextBox" Grid.Column="2" Grid.Row="1" Text="{Binding Person.FirstName, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}"></TextBox>

        <TextBox x:Name="LastNameTextBox" Grid.Column="2" Grid.Row="2" Text="{Binding Person.LastName, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}"></TextBox>

        <TextBox x:Name="EmailTextBox" Grid.Column="2" Grid.Row="3" Text="{Binding Person.Email, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}"></TextBox>

        <Button x:Name="SaveButton" Content="Save" Click="SaveButton_Click" Grid.Column="2" Grid.Row="4" ></Button>

        <ListBox x:Name="ErrorsListBox" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="5" BorderThickness="0"  DisplayMemberPath="ErrorContent" Height="auto" Foreground="Red" FontWeight="Bold" >

        </ListBox>

 

This XAML defines the UI for the application and binds 3 text boxes to FirstName, LastName and Email properties of an object of our Person type.

The ErrorsListBox control at the bottom will be used to display any validation errors.

 

The key points to note are on the text box bindings:

 

a.    First their mode = TwoWay – so when they are updated in the UI their data source is updated; i.e. the setters of the properties on the Person object are called with updated values.

b.    ValidatesOnExceptions = True – this tells Silverlight that if an exception occurs when the Silverlight Property System is updating the setters of a bound property, the validation template for the control is displayed to the user with the details of the exception (i.e. the exception’s message string) that was thrown in the bound setter.

c.    NotifyOnValidationError – True – this tells Silverlight to raise a routed event of  type BindingValidationError to be routed up the visual tree that can be handled by a parent control – in our case the LayoutRoot Grid.

 

4.    Add the following attribute to the LayoutRoot Grid:

 

BindingValidationError="LayoutRoot_BindingValidationError"

 

This adds the event handler for when the text boxes cause Silverlight to raise the routed event of type BindingValidationError and allows us to add logic to the event handler to handle the routed error.

 

5.    Replace the MainPage constructor in the MainPage class in the MainPage.xaml.cs class with the following code:

 

        private ObservableCollection<ValidationError> errors = new ObservableCollection<ValidationError>();

 

        public ObservableCollection<ValidationError> Errors

        {

            get { return errors; }

            set { errors = value; }

        }

        private Person person = new Person();

 

        public Person Person

        {

            get { return person; }

            set { person = value; }

        }

       

        public MainPage()

        {

            InitializeComponent();

            this.Loaded += new RoutedEventHandler(MainPage_Loaded);

        }

 

        void MainPage_Loaded(object sender, RoutedEventArgs e)

        {

            this.DataContext = this;

        }

 

This defines an ObservableCollection to hold the ValidationErrors that occur when binding validation fails (we will get to this in a moment).  The collection is made available through a property so it can be bound to by the ListBox.

A Person object is instantiated and made available through a property in this class so that the three text boxes can be bound to its properties.

When the page is loaded the DataContext of the UserControl is bound to this class.

 

6.    Paste the following code into the MainPage class:

 

        private void LayoutRoot_BindingValidationError(object sender, ValidationErrorEventArgs e)

        {

            switch(e.Action)

            {

                case ValidationErrorEventAction.Added:

                    errors.Add(e.Error);

                    break;

                case ValidationErrorEventAction.Removed:

                    errors.Remove(e.Error);

                    break;

            }

            ErrorsListBox.ItemsSource = this.errors;

        }

 

        private void SaveButton_Click(object sender, RoutedEventArgs e)

        {

            foreach (DependencyObject control in LayoutRoot.Children)

            {

                TextBox textbox = control as TextBox;

                if (textbox != null)

                {

                    BindingExpression expr = textbox.GetBindingExpression(TextBox.TextProperty);

                    expr.UpdateSource();

                }

            }

        }

 

This code defines two event handlers:

 

a.    The first is the event handler called when a child control of the LayoutRoot Grid control throws a binding exception.  For each exception thrown this event handler will be called by Silverlight.  Notice we identify if the ValidationError object passed into this event handler has been added or removed – i.e. a validation failed or passed (i.e. the error was removed by Silverlight).  If the validation error is added, it is added to our errors collection; if it was removed it is removed from our errors collection.  The errors collection is then bound to the list box so the error messages are displayed to the users.

b.    The second loops through the text boxes in the UI and forces their binding expressions to update their bound data sources – forcing the setters on the Person object to be called.

 

7.    Run the application:

 

 

8.    Click the save button:

 

 

See that all fields in the Person object threw exceptions that are displayed in the list box and the text boxes are highlighted in red.

 

9.    Set focus to the first name text box.

 

 

Note the popup label that displays the error message associated with the Person object property FirstName.

 

10.  Type a character in the first name textbox and tab out:

 

 

Notice the validation error label is no longer displayed for the first name property and the error message has disappeared from the list box.  Also note the textbox for the first name is no longer red.

 

11. Type a character in the last name textbox and tab out and enter a valid email address in the email text box and click the Save button:

 

 

Congratulations!  You have implemented validation in a custom object and hooked it up to use the standard Silverlight validation handlers.

 

What have we done?

 

We have created our own custom object with validation on its properties.

 

We have bound the custom object to Silverlight controls.

 

With configuration we have hooked up the standard Silverlight validation mechanisms for the bound controls.

 

We have hooked up the normal mechanism for a container control to trap and handle validation errors from child controls and display them to the user.

 

Conclusion

Silverlight has build in UI validation handling features that easily allow a developer to hook up validation in custom classes to controls in the UI layer and to capture and manage validation errors at a higher level in the control hierarchy in whatever way makes sense for their application.  Once again we see how Silverlight supports developing custom business applications with the infrastructure it delivers – with minimal coding by the developer to harness the value add supplied by Silverlight.

 

Posted on Monday, October 12, 2009 4:08 PM Silverlight | Back to top


Comments on this post: Silverlight – Easy Data Validation

# silverlight
Requesting Gravatar...
When you will post a sample of using a Stored proc with LinqToSql in RIA Services ?

I can't do it now....
Left by jeux r4 ds on Oct 12, 2009 10:43 PM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
Hi jeux r4 ds - I probably won't post on that particular subject (specific as it is), as MSFT has stated that Linq To SQL is deprecated and they will not be furthering their development of that particular tool set. They are focussing on Entity Framework in the future.

A topic that I will be addressing in the near future is transactions in RIA Services. Watch this space!
Left by Peter on Oct 19, 2009 10:26 PM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
excellent article. Thanks.
Left by forgetu on Oct 25, 2009 7:52 PM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
Thanks forgetu - I appreciate the feedback.
Left by Peter on Oct 28, 2009 8:57 PM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
Hi. Heres a problem with your code that I thought up:

Consider that you have a function that actually goes and adds a user into a database when the Save button is clicked. Right now when the button is pressed, all thats being done is that the validators are being forcibly fired. Nothing is being done to prevent submittion of this data to the database insertion function.

Is there a way to prevent the user from being inserted if the validation is not successful?
Left by Fahd on Oct 30, 2009 2:56 PM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
Here is how i handle it:

Private Sub SelectedCars_BindingValidationError(ByVal sender As Object, ByVal e As System.Windows.Controls.ValidationErrorEventArgs) Handles Me.BindingValidationError

If e.Action = ValidationErrorEventAction.Added Then
NbrValidationErrors += 1
Else
NbrValidationErrors -= 1
End If

If NbrValidationErrors < 0 Then NbrValidationErrors = 0

End Sub


in other code:

If NbrValidationErrors = 0 Then
UpdateDB()
End If
Left by Steven on Nov 02, 2009 10:18 AM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
Thanks for answering Steven. That solution would work great. I would use a similar approach, but for my logic as I am capturing the errors in an observable collection for display to the user, after the loop to force the updating of the source on the binding expressions of the controls in the save button click event handler, I would simply verify the length of the errors collection:

if (errors.Count > 0)
{
// Don't save
}
else
{
// Save the data
}

Make sense?
Left by Peter on Nov 02, 2009 9:55 PM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
Thanks, i went throug a thousand posts about validation and this is the only one that solves the problem of firing validation in every control. And even a validation summary. Awesome!!, thanks again. I was running in circles trying to find this myself.
Left by Ernesto on Dec 02, 2009 10:21 AM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
Thanks for the feedback Ernesto! This helps me understand if my blogs are hitting the mark. I am glad this one did for you.
Left by Peter on Dec 02, 2009 1:08 PM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
hello ... i am trying to add in a simple validation into my silverlight application... but i face exception unhandled by user code ... inside the class for example Leave.class... under the setter method i have my rules and i throw exception ... and then set the value of the property for example startdate = value .... when will i trigger the LayoutRoot_BindingValidationError method? so that i can have the red error message with my customised error message.
Left by lim on Jan 20, 2010 7:37 PM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
Awesome Dude :)
Simple but brilliant
Left by Venky on Mar 15, 2010 3:24 AM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
Nice Sample i had done same kind of sample but getting Argument Exception unhandled by code. Can u please look at the code at tell were its going wrong. Here is my code.
http://cid-92b2038f91c193eb.skydrive.live.com/browse.aspx/.Public?uc=1&isFromRichUpload=1
Left by Lavanya on Apr 11, 2010 6:30 PM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
Thanks for sharing Lavanya - I'll take a look and get back to you.
Left by Peter on Apr 12, 2010 10:48 AM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
Hi Lavanya, it's because you assign string.empty to the Name and LastName properties in the constructor for the Person class. This causes the exception to be thrown when the new Person() call is made before the object is assigned to the DataContext. You shouldn't assign the string.empty values in the constructor. Remove them and it'll work fine.
Left by Peter on Apr 14, 2010 10:43 PM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
Thanks peter,
I am able to solve this usin SL 4 IDataErrorInfo it works really good.
Left by Lavanya on Apr 21, 2010 12:58 PM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
how to same thing with icommand from viewmodel without buttonclick event?
Left by sarath on Nov 08, 2010 4:22 AM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
about my form have list wnenever i execute my page i will show the all records, after i create one more records that record only show me after i created in silverlight, what to do?
Left by suresh on Apr 07, 2011 4:55 PM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
if (expr != null)
expr.UpdateSource(); required.
Left by Kamal on Jan 19, 2012 1:58 AM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
Hi,
Iam getting error like ArgumentException was unhandled
Left by Ashwini on Jul 05, 2012 4:02 AM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
Doesnt work in chrome
Left by sapna mathpal on May 03, 2014 4:21 AM

# re: Silverlight – Easy Data Validation
Requesting Gravatar...
the data which we enter is saved somewhere so where these data is stored which we feed in this??
Left by vaibhav on Jul 09, 2014 7:58 AM

Your comment:
 (will show your gravatar)


Copyright © PeterTweed | Powered by: GeeksWithBlogs.net