Create new account I forgot my password    

Data Validation in Silverlight 4.0
Rating: 5 user(s) have rated this article Average rating: 5.0
Posted by: Mahesh Sabnis, on 7/28/2010, in category "Silverlight 2, 3 and 4"
Views: this article has been read 12578 times
Abstract: Silverlight 4.0 has several new features and it has been listed down well over here. One of the most exciting features of Silverlight 4.0, is its capability for building Line-of-Business (LOB) applications.

Data Validation in Silverlight 4.0
 
Silverlight 4.0 has several new features and it has been listed down well over here. One of the most exciting features of Silverlight 4.0, is its capability for building Line-of-Business (LOB) applications. Last week I was conducting a training program for one of my client on VS 2010, where I was asked lots of queries regarding Silverlight 4.0 and its capabilities as compare of its earlier versions. In this article, I will discuss one of the questions on Data Validation in Silverlight 4.0.
In this article, I have used ‘IDataErrorInfo’ interface which is newly provided in Silverlight 4.0 under System.ComponentModel namepsace. This interface needs to be implemented by the data entity class which helps in defining custom validations for data to be entered using Silverlight 4.0 UI controls.
 
Defining Data Entity class and implementing ‘IDataErrorInfo’
 
Step 1: Open VS2010 and create a new Silverlight 4.0 Application. Name it as ‘SILV4_DataValidationFeatures’.
Step 2: To this project, add a new class file and name it as ‘ApplicationClass’.
Step 3: In this class file, add the following class and name it as ‘Employee’ as below.
C#
public class Employee : INotifyPropertyChanged, IDataErrorInfo
{
    int _EmpNo;
 
    public int EmpNo
    {
        get
        {
            return _EmpNo;
        }
        set
        {
            _EmpNo = value;
            ChangeValue("EmpNo");
        }
    }
    string _EmpName;
 
    public string EmpName
    {
        get
        {
            return _EmpName;
        }
        set
        {
            _EmpName = value;
            ChangeValue("EmpName");
        }
    }
    int _Salary;
 
    public int Salary
    {
        get
        {
            return _Salary;
        }
        set
        {
            _Salary = value;
            ChangeValue("Salary");
        }
    }
    int _DeptNo;
 
    public int DeptNo
    {
        get
        {
            return _DeptNo;
        }
        set
        {
            _DeptNo = value;
            ChangeValue("DeptNo");
        }
    }
 
    public event PropertyChangedEventHandler PropertyChanged;
 
    public void ChangeValue(string PropName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(PropName));
        }
    }
 
    string err;
    public string Error
    {
        get { return err; }
    }
 
    public string this[string columnName]
    {
        get
        {
            string msg = null;
            if (columnName == "EmpNo")
            {
                if (EmpNo <= 0 || EmpNo.ToString().Length > 5)
                {
                    msg = "EmpNo must not be Negative or Lenght must not be more than 5.";
                }
            }
 
            if (columnName == "EmpName")
            {
                if (EmpName.Equals(string.Empty))
                {
                    msg = "EmpName is must,Please enter Correct Value.";
                }
            }
            if (columnName == "Salary")
            {
                if (Salary <= 0)
                {
                    msg = "Salary must not be Negative.";
                }
            }
            if (columnName == "DeptNo")
            {
                if (DeptNo <= 0)
                {
                    msg = "DeptNo must not be Negative.";
                }
            }
 
            return msg;
        }
    }
}
 
VB.NET
Public Class Employee
      Implements INotifyPropertyChanged, IDataErrorInfo
      Private _EmpNo As Integer
 
      Public Property EmpNo() As Integer
            Get
                  Return _EmpNo
            End Get
            Set(ByVal value As Integer)
                  _EmpNo = value
                  ChangeValue("EmpNo")
            End Set
      End Property
      Private _EmpName As String
 
      Public Property EmpName() As String
            Get
                  Return _EmpName
            End Get
            Set(ByVal value As String)
                  _EmpName = value
                  ChangeValue("EmpName")
            End Set
      End Property
      Private _Salary As Integer
 
      Public Property Salary() As Integer
            Get
                  Return _Salary
            End Get
            Set(ByVal value As Integer)
                  _Salary = value
                  ChangeValue("Salary")
            End Set
      End Property
      Private _DeptNo As Integer
 
      Public Property DeptNo() As Integer
            Get
                  Return _DeptNo
            End Get
            Set(ByVal value As Integer)
                  _DeptNo = value
                  ChangeValue("DeptNo")
            End Set
      End Property
 
Public Event PropertyChanged As PropertyChangedEventHandler
 
      Public Sub ChangeValue(ByVal PropName As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(PropName))
      End Sub
 
      Private err As String
      Public ReadOnly Property [Error]() As String
            Get
                  Return err
            End Get
      End Property
 
      Default Public ReadOnly Property Item(ByVal columnName As String) As String
            Get
                  Dim msg As String = Nothing
                  If columnName = "EmpNo" Then
                        If EmpNo <= 0 OrElse EmpNo.ToString().Length > 5 Then
                              msg = "EmpNo must not be Negative or Lenght must not be more than 5."
                        End If
                  End If
 
                  If columnName = "EmpName" Then
                        If EmpName.Equals(String.Empty) Then
                              msg = "EmpName is must,Please enter Correct Value."
                        End If
                  End If
                  If columnName = "Salary" Then
                        If Salary <= 0 Then
                              msg = "Salary must not be Negative."
                        End If
                  End If
                  If columnName = "DeptNo" Then
                        If DeptNo <= 0 Then
                              msg = "DeptNo must not be Negative."
                        End If
                  End If
 
                  Return msg
            End Get
      End Property
}
 
The Employee class implements ‘IDataErrorInfo’ interface. This provide property ‘Error’ and an indexer which takes property name for custom validation. In the indexer, I have written my own validation error messages.
Step 4: In the class file added in the previous steps, write the following data storage class:
C#
public class EmployeeCollection
{
    public ObservableCollection<Employee> ColEmployee { get; set; }
 
    public EmployeeCollection()
    {
        ColEmployee = new ObservableCollection<Employee>();
        ColEmployee.Add(new Employee() { EmpNo = 101, EmpName = "Mahesh", Salary = 76000, DeptNo = 10 });
        ColEmployee.Add(new Employee() { EmpNo = 102, EmpName = "Amey", Salary = 66000, DeptNo = 20 });
        ColEmployee.Add(new Employee() { EmpNo = 103, EmpName = "Rajesh", Salary = 56000, DeptNo = 10 });
        ColEmployee.Add(new Employee() { EmpNo = 104, EmpName = "Rahul", Salary = 77000, DeptNo = 20 });
        ColEmployee.Add(new Employee() { EmpNo = 105, EmpName = "Ajay", Salary = 79000, DeptNo = 30 });
        ColEmployee.Add(new Employee() { EmpNo = 106, EmpName = "Pradnya", Salary = 86000, DeptNo = 10 });
    }
}
 
VB.NET
Public Class EmployeeCollection
      Public Property ColEmployee() As ObservableCollection(Of Employee)
 
      Public Sub New()
            ColEmployee = New ObservableCollection(Of Employee)()
            ColEmployee.Add(New Employee() With {.EmpNo = 101, .EmpName = "Mahesh", .Salary = 76000, .DeptNo = 10})
            ColEmployee.Add(New Employee() With {.EmpNo = 102, .EmpName = "Amey", .Salary = 66000, .DeptNo = 20})
            ColEmployee.Add(New Employee() With {.EmpNo = 103, .EmpName = "Rajesh", .Salary = 56000, .DeptNo = 10})
            ColEmployee.Add(New Employee() With {.EmpNo = 104, .EmpName = "Rahul", .Salary = 77000, .DeptNo = 20})
            ColEmployee.Add(New Employee() With {.EmpNo = 105, .EmpName = "Ajay", .Salary = 79000, .DeptNo = 30})
            ColEmployee.Add(New Employee() With {.EmpNo = 106, .EmpName = "Pradnya", .Salary = 86000, .DeptNo = 10})
      End Sub
End Class
 
Creating Silverlight 4.0 UI
 
Step 1: Open MainPage.Xaml and write the following Xaml for generating UI:
<UserControl x:Class="SILV4_DatavalidationFeatures.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     xmlns:src="clr-namespace:SILV4_DatavalidationFeatures"        
    mc:Ignorable="d"
    d:DesignHeight="322" d:DesignWidth="668"
             xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
    <UserControl.Resources>
        <src:EmployeeCollection x:Key="EmpDs"></src:EmployeeCollection>
          <Style TargetType="TextBlock">
            <Setter Property="Width" Value="100"></Setter>
            <Setter Property="Foreground" Value="Black"></Setter>
            <Setter Property="Height" Value="50"></Setter>
        </Style>
    </UserControl.Resources>
   
    <Grid x:Name="LayoutRoot" Background="White" Height="320" Width="667"
           DataContext="{Binding Path=ColEmployee, Source={StaticResource EmpDs}}">
            <Grid.ColumnDefinitions>
            <ColumnDefinition Width="303*" />
            <ColumnDefinition Width="364*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="270"></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock Height="45" HorizontalAlignment="Left" Margin="175,9,0,0"
                   Name="textBlock1" Text="Employee Information System"
                   VerticalAlignment="Top" Width="402" TextAlignment="Center"
                   FontSize="22" Foreground="#FFB10000" FontWeight="ExtraBold"
                   Grid.ColumnSpan="2" Grid.RowSpan="2" />
        <Grid Grid.Row="1" Grid.Column="0" Name="grdRecord">
        <TextBlock Grid.Row="1" Height="23" HorizontalAlignment="Left"
                   Margin="12,21,0,0" Name="textBlock2" Text="EmpNo"
                   VerticalAlignment="Top" Width="100" />
        <TextBlock Grid.Row="1" Height="23"
                   HorizontalAlignment="Left" Margin="12,70,0,0"
                   Name="textBlock3" Text="EmpName"
                   VerticalAlignment="Top" Width="100" />
        <TextBlock Grid.Row="1" Height="23"
                   HorizontalAlignment="Left" Margin="12,117,0,0"
                   Name="textBlock4" Text="Salary"
                   VerticalAlignment="Top" Width="100" />
        <TextBlock Grid.Row="1" Height="23"
                   HorizontalAlignment="Left" Margin="12,160,0,0" Name="textBlock5"
                   Text="DeptNo" VerticalAlignment="Top" Width="100" />
        <TextBox Grid.Row="1" Height="23"
                 HorizontalAlignment="Left" Margin="148,21,0,0"
                 Name="txtEno"
                 Text="{Binding Path=EmpNo,Mode=TwoWay,ValidatesOnDataErrors=True}"
                 VerticalAlignment="Top" Width="120" />
        <TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left"
                 Margin="148,66,0,0" Name="txtEname"
                 Text="{Binding Path=EmpName,Mode=TwoWay,ValidatesOnDataErrors=True}"
                 VerticalAlignment="Top" Width="120"
                 />
        <TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left"
                 Margin="148,117,0,0" Name="txtSalary"
                 Text="{Binding Path=Salary,Mode=TwoWay,ValidatesOnDataErrors=True,StringFormat=C}"
                 VerticalAlignment="Top" Width="120" />
        <TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left"
                 Margin="148,160,0,0" Name="txtDno"
                 Text="{Binding Path=DeptNo,Mode=TwoWay,ValidatesOnDataErrors=True}"
                 VerticalAlignment="Top" Width="120" />
        <Button Content="Add" Height="23" HorizontalAlignment="Left"
                Margin="55,233,0,0" Name="btnAdd" VerticalAlignment="Top"
                Width="133" Click="btnAdd_Click" />
        </Grid>
        <sdk:DataGrid AutoGenerateColumns="False"
                      Grid.Column="1" Grid.Row="1"
                      Height="243" HorizontalAlignment="Left" Margin="11,10,0,0"
                      Name="dgEmp" VerticalAlignment="Top" Width="340"
                      ItemsSource="{Binding}">
            <sdk:DataGrid.Columns>
                <sdk:DataGridTextColumn Binding="{Binding EmpNo}"
                                        Width="80" Header="EmpNo"></sdk:DataGridTextColumn>
                <sdk:DataGridTextColumn Binding="{Binding EmpName}"
                                        Width="120" Header="EmpName"></sdk:DataGridTextColumn>
                <sdk:DataGridTextColumn Binding="{Binding Salary}"
                                        Width="80" Header="Salary"></sdk:DataGridTextColumn>
                <sdk:DataGridTextColumn Binding="{Binding DeptNo}"
                                        Width="80" Header="DeptNo"></sdk:DataGridTextColumn>
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>
    </Grid>
</UserControl>
 
In the above xaml, the code marked in ‘Green’ represents the import of the namespace and the declaration an object of the ‘EmployeeCollection’ data store class. The code which is marked by ‘Yellow’ represents how properties from data entity class ‘Employee’ are bound with textboxes and data validation mode. This automatically invalidates the control when user enters invalidate input value. Since the ‘Employee’ class implements ‘IDataErrorInfo’, and its object is bound with textbox, the values entered in textbox will be delivered on the employee object to the concern property. This further verifies value against the code in the indexer. If the value is invalid, then the control shows a ‘Red’ outline and the notification as a tip.
Step 2:    Open MainPage.Xaml.cs and write the following code in various events:
C#
Employee objEmp;
 
        EmployeeCollection objCol;
        public MainPage()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }
 
        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            objEmp = new Employee();
            objCol = new EmployeeCollection();
 
            objEmp = (from emp in objCol.ColEmployee
                     select new Employee()
                     {
                         EmpNo = emp.EmpNo,
                         EmpName = emp.EmpName,
                         DeptNo = emp.DeptNo,
                         Salary = emp.Salary
                     }).First() ;
 
            
            this.DataContext = this;
 
             grdRecord.DataContext = objEmp;
         
        }
 
       private void btnAdd_Click(object sender, RoutedEventArgs e)
        {
            if (Validation.GetHasError(txtEno) || Validation.GetHasError(txtEname)
                || Validation.GetHasError(txtSalary) || Validation.GetHasError(txtDno))
            {
                MessageBox.Show("Please satisfy the Validation Condition");
            }
            else
            {
                objCol.ColEmployee.Add(objEmp);
                dgEmp.DataContext = objCol.ColEmployee;
            }
        }
 
VB.NET
Private objEmp As Employee
 
            Private objCol As EmployeeCollection
            Public Sub New()
                  InitializeComponent()
                  AddHandler Loaded, AddressOf MainPage_Loaded
            End Sub
 
            Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
                  objEmp = New Employee()
                  objCol = New EmployeeCollection()
 
                  objEmp = (
                      From emp In objCol.ColEmployee
                      Select New Employee() With {.EmpNo = emp.EmpNo, .EmpName = emp.EmpName, .DeptNo = emp.DeptNo, .Salary = emp.Salary}).First()
 
 
                  Me.DataContext = Me
 
                   grdRecord.DataContext = objEmp
 
            End Sub
 
         Private Sub btnAdd_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
                  If Validation.GetHasError(txtEno) OrElse Validation.GetHasError(txtEname) OrElse Validation.GetHasError(txtSalary) OrElse Validation.GetHasError(txtDno) Then
                        MessageBox.Show("Please satisfy the Validation Condition")
                  Else
                        objCol.ColEmployee.Add(objEmp)
                        dgEmp.DataContext = objCol.ColEmployee
                  End If
         End Sub
In the above code, the loaded event queries to the ‘EmployeeCollection’ class and fetches the first record. This is then bound with the textboxes using the yellow marked statement we saw a short while ago. The Add Button click event here checks the validation on every textbox; if the value is invalid then the message displayed else the record will be added in the collection which will be shown in the datagrid.
Step 3: Run the application and try to insert some invalid values, e.g. put negative value for EmpNo the following result will be displayed:
EmployeeInformationSystem
The error tip shows the custom validation information which you have written in the ‘Employee’ data entity class.
Conclusion: Silverlight 4.0, now helps us to build LOB applications using such custom validation mechanism, whenever we need to work on some DML operations.
The entire source code of this article can be downloaded over here
If you liked the article,  Subscribe to the RSS Feed or Subscribe Via Email  









Page copy protected against web site content infringement by Copyscape


How would you rate this article?

User Feedback

Post your comment
Name:  
E-mail: (Will not be displayed)
Comment:
Insert Cancel

NEWSLETTER