Data Validation in Silverlight 4

Exclusive offer: get 50% off this eBook here
Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

Microsoft Silverlight 4 Business Application Development: Beginner’s Guide — Save 50%

Build enterprise-ready business applications with Microsoft Silverlight 4 with this book and eBook

$32.99    $16.50
by Frank LaVigne | April 2010 | Beginner's Guides Microsoft Web Development Web Graphics & Video

Packt are due to launch a new Enterprise brand, into which future Silverlight titles will be published. For more information on that launch, look here.

In this article by Frank LaVigne, author of Microsoft Silverlight 4 Business Application Development, we shall:

  • Bind the data from a data object to Silverlight controls
  • Validate data and display feedback to the user

With Silverlight, data validation has been fully implemented, allowing controls to be bound to data objects and those data objects to handle the validation of data and provide feedback to the controls via the Visual State Machine.

The Visual State Machine is a feature of Silverlight used to render to views of a control based on its state. For instance, the mouse over state of a button can actually change the color of the button, show or hide parts of the control, and so on.

Controls that participate in data validation contain a ValidationStates group that includes a Valid, InvalidUnfocused, and InvalidFocused states. We can implement custom styles for these states to provide visual feedback to the user.

Data object

In order to take advantage of the data validation in Silverlight, we need to create a data object or client side business object that can handle the validation of data.

Time for action – creating a data object

We are going to create a data object that we will bind to our input form to provide validation. Silverlight can bind to any properties of an object, but for validation we need to do two way binding, for which we need both a get and a set accessor for each of our properties. In order to use two way binding, we will need to implement the INotifyPropertyChanged interface that defines a PropertyChanged event that Silverlight will use to update the binding when a property changes.

  1. Firstly, we will need to switch over to Visual Studio and add a new class named CustomerInfo to the Silverlight project:
  2. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  3. Replace the body of the CustomerInfo.cs file with the following code:
  4. using System;
    using System.ComponentModel;

    namespace CakeORamaData
    {
    public class CustomerInfo : INotifyPropertyChanged
    {
    public event PropertyChangedEventHandler PropertyChanged =
    delegate { };

    private string _cutomerName = null;
    public string CustomerName
    {
    get { return _cutomerName; }
    set
    {
    if (value == _cutomerName)
    return;

    _cutomerName = value;
    OnPropertyChanged("CustomerName");
    }
    }
    private string _phoneNumber = null;
    public string PhoneNumber
    {
    get { return _phoneNumber; }
    set
    {
    if (value == _phoneNumber)
    return;
    _phoneNumber = value;
    OnPropertyChanged("PhoneNumber");
    }
    }
    private string _email = null;
    public string Email
    {
    get { return _email; }
    set
    {
    if (value == _email)
    return;
    _email = value;
    OnPropertyChanged("Email");
    }
    }
    private DateTime _eventDate = DateTime.Now.AddDays(7);
    public DateTime EventDate
    {
    get { return _eventDate; }
    set
    {
    if (value == _eventDate)
    return;
    _eventDate = value;
    OnPropertyChanged("EventDate");
    }
    }
    private void OnPropertyChanged(string propertyName)
    {
    PropertyChanged(this, new PropertyChangedEventArgs
    (propertyName));
    }
    }
    }

Code Snippets
Code snippets are a convenient way to stub out repetitive code and increase productivity, by removing the need to type a bunch of the same syntax over and over.

The following is a code snippet used to create properties that execute the OnPropertyChanged method and can be very useful when implementing properties on a class that implements the INotifyPropertyChanged interface.

To use the snippet, save the file as propnotify.snippet to your hard drive.

In Visual Studio go to Tools | Code Snippets Manager (Ctrl + K, Ctrl + B) and click the Import button. Find the propnotify.snippet file and click Open, this will add the snippet.

To use the snippet in code, simply type propnotify and hit the Tab key; a property will be stubbed out allowing you to change the name and type of the property.

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/
VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>propnotify</Title>
<Shortcut>propnotify</Shortcut>
<Description>Code snippet for a property that raises
the PropertyChanged event in a class.</Description>
<Author>Cameron Albert</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>type</ID>
<ToolTip>Property type</ToolTip>
<Default>int</Default>
</Literal>
<Literal>
<ID>property</ID>
<ToolTip>Property name</ToolTip>
<Default>MyProperty</Default>
</Literal>
<Literal>
<ID>field</ID>
<ToolTip>Private field</ToolTip>
<Default>_myProperty</Default>
</Literal>
<Literal>
<ID>defaultValue</ID>
<ToolTip>Default Value</ToolTip>
<Default>null</Default>
</Literal>
</Declarations>
<Code Language="csharp">
<![CDATA[private $type$ $field$ = $defaultValue$;
public $type$ $property$
{
get { return $field$; }
set
{
if (value == $field$)
return;
$field$ = value;
OnPropertyChanged("$property$");
}
}
$end$]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

What just happened?

We created a data object or client-side business object that we can use to bind to our input controls.

We implemented the INotifyPropertyChanged interface, so that our data object can raise the PropertyChanged event whenever the value of one of its properties is changed. We also defined a default delegate value for the PropertyChanged event to prevent us from having to do a null check when raising the event. Not to mention we have a nice snippet for stubbing out properties that raise the PropertyChanged event.

Now we will be able to bind this object to Silverlight input controls and the controls can cause the object values to be updated so that we can provide data validation from within our data object, rather than having to include validation logic in our user interface code.

Data binding

We are going to bind our CustomerInfo object to our data entry form, using Blend. Be sure to build the solution before switching back over to Blend.

  1. With MainPage.xaml open in Blend, select the LayoutRoot control. In the Properties panel enter DataContext in the search field and click the New button:
  2. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  3. In the dialog that opens, select the CustomerInfo class and click OK:
  4. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  5. Blend will set the DataContext of the LayoutRoot to an instance of a CustomerInfo class:
  6. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  7. Blend inserts a namespace to our class; set the Grid.DataContext in the XAML of MainPage.xaml:
  8. xmlns:local="clr-namespace:CakeORamaData"

    <Grid.DataContext>
    <local:CustomerInfo/>
    </Grid.DataContext>

  9. Now we will bind the value of CustomerName to our customerName textbox. Select the customerName textbox and then on the Properties panel enter Text in the search field. Click on the Advanced property options icon, which will open a context menu for choosing an option:
  10. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  11. Click on the Data Binding option to open the Create Data Binding dialog:
  12. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  13. In the Create Data Binding dialog (on the Explicit Data Context tab), click the arrow next to the CustomerInfo entry in the Fields list and select CustomerName:
  14. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  15. At the bottom of the Create Data Binding dialog, click on the Show advanced properties arrow to expand the dialog and display additional binding options:
  16. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  17. Ensure that TwoWay is selected in the Binding direction option and that Update source when is set to Explicit. This creates a two-way binding, meaning that when the value of the Text property of the textbox changes the underlying property, bound to Text will also be updated. In our case the customerName property of the CustomerInfo class:
  18. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  19. Click OK to close the dialog; we can now see that Blend indicates that this property is bound by the yellow border around the property input field:
  20. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  21. Repeat this process for both the phoneNumber and emailAddress textbox controls, to bind the Text property to the PhoneNumber and Email properties of the CustomerInfo class. You will see that Blend has modified our XAML using the Binding Expression:

  22. <TextBox x:Name="customerName" Margin="94,8,8,0" Text="{Binding
    CustomerName, Mode=TwoWay, UpdateSourceTrigger=Explicit}"
    TextWrapping="Wrap" VerticalAlignment="Top" Grid.Column="1" Grid.
    Row="1" MaxLength="40"/>

  23. In the Binding Expression code the Binding is using the CustomerName property as the binding Path. The Path (Path=CustomerName) attribute can be omitted since the Binding class constructor accepts the path as an argument.
  24. The UpdateSourceTrigger is set to Explicit, which causes any changes in the underlying data object to force a re-bind of the control.
  25. For the eventDate control, enter SelectedDate into the Properties panel search field and following the same process of data binding, select the EventDate property of the CustomerInfo class. Remember to ensure that TwoWay/Explict binding is selected in the advanced options:
  26. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

Microsoft Silverlight 4 Business Application Development: Beginner’s Guide Build enterprise-ready business applications with Microsoft Silverlight 4 with this book and eBook
Published: April 2010
eBook Price: $32.99
Book Price: $54.99
See more
Select your format and quantity:

What just happened?

We utilized Silverlight data binding to bind our input controls to properties of our CustomerInfo class. In the process, we setup the binding to be two way, allowing the controls to set the property values of the CustomerInfo class, thus removing the need to add a bunch of text changed event handlers to manually do it ourselves, saving us more time in development.

We also had a chance to see how much time using Blend can save and how easy it is to add data bindings to controls. We saw the Binding Expression syntax used to define a Binding in XAML and also how to setup a Binding so that changes to the underlying object cause the control to re-bind the value.

Validation

Before we submit information to the server using our WCF service, we need to validate the data input from the user and provide feedback to the user if invalid information is supplied.

Silverlight can report a validation error in one of three scenarios:

  • Exceptions thrown from the binding type converter
  • Exceptions thrown from the binding object's set accessor
  • Exceptions thrown from one of the validation attributes found in the DataAnnotations assembly

We will focus on the set accessor method as this provides the simplest way to get our data validated.

Time for action – validating data input

We will make use of some additional properties of Binding to allow the controls to display the validation states. Blend does not provide a visual way for us to add these additional properties so we have to do it manually in XAML.

  1. Switch to the XAML view of the MainPage.xaml in Blend and scroll down to where our textbox controls are located.
  2. Within the Binding Expression (between the { and } of the Binding), add the following two attributes to each one of the bindings on our input controls:
  3. {Binding CustomerName, Mode=TwoWay, UpdateSourceTrigger=Explicit,
    NotifyOnValidationError=True, ValidatesOnExceptions=True }

  4. The NotifyOnValidationError and ValidatesOnException will both cause the control to display an error message if a validation or exception error occurs when the value of the bound property changes.
  5. Now we need to modify our data object to provide validation in the set accessor of each property. Change the CustomerInfo.cs file to implement our property validation:
  6. using System;
    using System.ComponentModel;
    using System.Text.RegularExpressions;

    namespace CakeORamaData
    {
    public class CustomerInfo : INotifyPropertyChanged
    {
    private static Regex RegexPhoneNumber = new Regex(@"((\
    (\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}", RegexOptions.Multiline);
    private static Regex RegexEmail = new Regex(@"^([\w\-
    \.]+)@((\[([0-9]{1,3}\.){3}[0-9]{1,3}\])|(([\w\-]+\.)+)([a-zA-
    Z]{2,4}))$", RegexOptions.Multiline | RegexOptions.IgnoreCase);
    public event PropertyChangedEventHandler PropertyChanged =
    delegate { };
    private string _cutomerName = null;
    public string CustomerName
    {
    get { return _cutomerName; }
    set
    {
    if (value == _cutomerName)
    return;
    if (String.IsNullOrEmpty(value))
    throw new ArgumentException("Customer Name is
    required.");
    if (value.Length < 3 || value.Length > 40)
    throw new ArgumentException("Customer Name must be at
    least 3 characters and not more than 40 characters
    in length.");
    _cutomerName = value;
    OnPropertyChanged("CustomerName");
    }
    }
    private string _phoneNumber = null;
    public string PhoneNumber
    {
    get { return _phoneNumber; }
    set
    {
    if (value == _phoneNumber)
    return;
    if (String.IsNullOrEmpty(value))
    throw new ArgumentException("Phone Number is
    required.");
    if (!RegexPhoneNumber.IsMatch(value))
    throw new ArgumentException("A valid phone number in the
    format (XXX) XXX-XXXX or XXX-XXX-XXXX is required.");
    _phoneNumber = value;
    OnPropertyChanged("PhoneNumber");
    }
    }
    private string _email = null;
    public string Email
    {
    get { return _email; }
    set
    {
    if (value == _email)
    return;
    if (String.IsNullOrEmpty(value))
    throw new ArgumentException("Email Address is
    required.");
    if (!RegexEmail.IsMatch(value))
    throw new ArgumentException("A valid email address is
    required.");
    _email = value;
    OnPropertyChanged("Email");
    }
    }
    private DateTime _eventDate = DateTime.Now.AddDays(7);
    public DateTime EventDate
    {
    get { return _eventDate; }
    set
    {
    if (value == _eventDate)
    return;
    _eventDate = value;
    OnPropertyChanged("EventDate");
    }
    }
    private void OnPropertyChanged(string propertyName)
    {
    PropertyChanged(this, new PropertyChangedEventArgs
    (propertyName));
    }
    }
    }

  7. Open the MainPage.xaml.cs file and in the constructor add the following code to set the LayoutRoot.DataContext with a new instance of CustomerInfo:
  8. public MainPage()
    {
    this.Loaded += new RoutedEventHandler(MainPage_Loaded);
    InitializeComponent();
    }
    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
    LayoutRoot.DataContext = new CustomerInfo();
    }

  9. Also within the MainPage.xaml file in the submitButton_Click event handler, we will add code to force validation of our data object:
  10. private void submitButton_Click(object sender, System.Windows.
    RoutedEventArgs e)
    {
    var bindingExpression = customerName.GetBindingExpression(TextBo
    x.TextProperty);
    bindingExpression.UpdateSource();
    bindingExpression = phoneNumber.GetBindingExpression(TextBox.
    TextProperty);
    bindingExpression.UpdateSource();
    bindingExpression = emailAddress.GetBindingExpression(TextBox.
    TextProperty);
    bindingExpression.UpdateSource();
    }

  11. In Visual Studio, choose Debug | Start without Debugging from the file menu. We are not going to debug because our properties throw exceptions and we just want to see the result. Just click the Submit button and all the textbox controls will highlight with red borders:
  12. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  13. If you hover over the small arrow in the top-right corner of the textbox you will see the error message from the data object:
  14. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

What just happened?

We implemented simple data validation in our objects and let the built in Silverlight binding process handle the rest by including some additional attributes in the Binding Expression. We implemented the INotifyPropertyChanged interface in our data object so that the data will be re-bound whenever the values are changed. We also made use of regular expressions to ensure that the phone number and email address are in a valid format.

Summary

In this article, we discussed the following:

  • How to create a data object for use with binding
  • How to bind data from a data object to Silverlight controls
  • How to provide input validation using the built-in validation states

If you have read this article you may be interested to view :

Microsoft Silverlight 4 Business Application Development: Beginner’s Guide Build enterprise-ready business applications with Microsoft Silverlight 4 with this book and eBook
Published: April 2010
eBook Price: $32.99
Book Price: $54.99
See more
Select your format and quantity:

About the Author :


Frank LaVigne

Frank LaVigne has been hooked on software development since he was 12, when he got his own Commodore 64 computer. Since then, he's worked as developer for fi nancial fi rms on Wall Street and also in Europe. He has worked on various Tablet PC soluti ons and on building advanced user experiences in Silverlight and WPF. He lives in the suburbs of Washington, DC. He founded the CapArea.NET User Group Silverlight Special Interest Group and has been recognized by Microsoft as a Tablet PC MVP. He blogs regularly at www.FranksWorld.com.

 

Books From Packt


Microsoft Silverlight 4 Data and Services Cookbook
Microsoft Silverlight 4 Data and Services Cookbook

.NET Compact Framework 3.5 Data Driven Applications
.NET Compact Framework 3.5 Data Driven Applications

Grok 1.0 Web Development
Grok 1.0 Web Development

Django 1.2 E-commerce
Django 1.2 E-commerce

Firebug 1.5: Editing, Debugging, and Monitoring Web Pages
Firebug 1.5: Editing, Debugging, and Monitoring Web Pages

OpenX Ad Server: Beginner's Guide
OpenX Ad Server: Beginner's Guide

3D Game Development with Microsoft Silverlight 3: Beginner's Guide
3D Game Development with Microsoft Silverlight 3: Beginner's Guide

MediaWiki 1.1 Beginner's Guide
MediaWiki 1.1 Beginner's Guide


Your rating: None Average: 3 (2 votes)
Why wouldn't you use the by
Why wouldn't you use the IDataErrorInfo if your tageting SL 4?
geat article! by
thanks for sharing this is very help full :)

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
T
d
q
g
n
V
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software