





















































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.
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.
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.
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 >
<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>
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.
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.
<Grid.DataContext>
<local:CustomerInfo/>
</Grid.DataContext>
<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"/>