WPF 3.5 New Data Validation Feature

Typically when you perform data binding in WPF, it is necessary for you to think of data entry validations. With WPF 3.5, new data validation support is provided for validating user entries. 'IDataErrorInfo', the interface provided to offer custom error information. For explaining the new validation in WPF 3.5, see the following class:

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace WPF_DataValidation
{
public class clsEmployee : IDataErrorInfo
{
private int _EmpNo;

public int EmpNo
{
get { return _EmpNo; }
set { _EmpNo = value; }
}
private string _EmpName = "";

public string EmpName
{
get { return _EmpName; }
set { _EmpName = value; }
}
private int _Salary;

public int Salary
{
get { return _Salary; }
set { _Salary = value; }
}

#region IDataErrorInfo Members

public string Error
{
get { return null; }
}

public string this[string fieldName]
{
get
{
string result = null;

#region For Validating EmpNo
if (fieldName == "EmpNo")
{
if (this._EmpNo < 0)
{
result = "Emp No should not be less than 0";
}
}
#endregion

#region
For Validating EmpName
if (fieldName == "EmpName")
{
if (this._EmpName == string.Empty)
{
result = "Employee Name should not be blank";
}
else
{
foreach (char c in this._EmpName)
{
if (c < 65 c > 122 (c >= 91 && c <= 96))
{
result = "Employee Name should " +
"not Contain Special Characters";
}
}
}
}
#endregion

#region
For Validating Salary
if (fieldName == "Salary")
{
if (this._Salary < 0)
{
result = "Salary should not be less than Zero";
}
}
#endregion

return
result;
}
}

#endregion
}
}

VB.NET

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.ComponentModel

Namespace WPF_DataValidation
Public Class clsEmployee
Implements IDataErrorInfo
Private _EmpNo As Integer

Public Property
EmpNo() As Integer
Get
Return
_EmpNo
End Get
Set
(ByVal value As Integer)
_EmpNo = value
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
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
End Set
End Property

#Region
"IDataErrorInfo Members"

Public ReadOnly Property [Error]() As String _
Implements IDataErrorInfo.Error
Get
Return Nothing
End Get
End Property

Default Public ReadOnly Property
Item(ByVal fieldName As String) _
As String Implements IDataErrorInfo.Item
Get
Dim
result As String = Nothing

' #Region "For Validating EmpNo"
If fieldName = "EmpNo" Then
If Me
._EmpNo < 0 Then
result = "Emp No should not be less than 0"
End If
End If
' #End Region

' #Region "For Validating EmpName"
If fieldName = "EmpName" Then
If Me
._EmpName = String.Empty Then
result = "Employee Name should not be blank"
Else
For Each
c As Char In Me._EmpName
If AscW(c) < 65 OrElse AscW(c) > 122 OrElse _
(c >= 91 AndAlso c <= 96) Then
result = "Employee Name should " & _
"not Contain Special Characters"
End If
Next
c
End If
End If
' #End Region

' #Region "For Validating Salary"
If fieldName = "Salary" Then
If Me
._Salary < 0 Then
result = "Salary should not be less than Zero"
End If
End If
' #End Region

Return result
End Get
End Property

#End Region
End Class
End Namespace

IDataErrorInfo provides the 'this' property, where customized validation logic can be implemented. See the following XAML where the validation is specified for every textbox control:

<Window x:Class="WPF_DataValidation.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="525"
xmlns:src="clr-namespace:WPF_DataValidation">

<
Window.Resources>
<
src:clsEmployee x:Key="Emp"></src:clsEmployee>

<!--The Too tip for the textbox-->
<Style x:Key="txterror" TargetType="{x:Type TextBox}">
<
Style.Triggers>
<
Trigger Property="Validation.HasError" Value="true">
<
Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors)[0].ErrorContent}"></Setter>
<
Setter Property="Background" Value="Red"></Setter>
</
Trigger>
</
Style.Triggers>
</
Style>
</
Window.Resources>

<
Grid>
<
Label Height="28" HorizontalAlignment="Left" Margin="12,27,0,0"
Name="label1" VerticalAlignment="Top" Width="151">Emp. No</Label>
<
TextBox Height="23"
Margin="262,27,96,0"
Name="txteno"
VerticalAlignment="Top" Style="{StaticResource txterror}">
<
TextBox.Text>
<
Binding Path="EmpNo" Source="{StaticResource Emp}"
ValidatesOnDataErrors="True"
UpdateSourceTrigger="PropertyChanged">
<
Binding.ValidationRules>
<
ExceptionValidationRule></ExceptionValidationRule>
</
Binding.ValidationRules>
</
Binding>
</
TextBox.Text>
</
TextBox>
<
Label Height="28" HorizontalAlignment="Left" Margin="12,72,0,0"
Name="label2" VerticalAlignment="Top" Width="151">Emp. Name</Label>
<
Label HorizontalAlignment="Left" Margin="12,122,0,112" Name="label3"
Width="151">Salary</Label>
<
TextBox Height="23" Margin="262,74,96,0" Name="txtename"
VerticalAlignment="Top" Style="{StaticResource txterror}">
<
TextBox.Text>
<
Binding Path="EmpName" Source="{StaticResource Emp}"
ValidatesOnDataErrors="True"
UpdateSourceTrigger="PropertyChanged">
<
Binding.ValidationRules>
<
ExceptionValidationRule></ExceptionValidationRule>
</
Binding.ValidationRules>
</
Binding>
</
TextBox.Text>
</
TextBox>
<
TextBox Margin="262,127,96,112" Name="txtsal"
Style="{StaticResource txterror}">
<
TextBox.Text>
<
Binding Path="Salary" Source="{StaticResource Emp}"
ValidatesOnDataErrors="True"
UpdateSourceTrigger="PropertyChanged">
<
Binding.ValidationRules>
<
ExceptionValidationRule></ExceptionValidationRule>
</
Binding.ValidationRules>
</
Binding>
</
TextBox.Text>
</
TextBox>
<
Button Height="23" Margin="12,0,96,55" Name="button1"
VerticalAlignment="Bottom">Button</Button>
</
Grid>
</
Window>


Style trigger is defined targeting to the Textbox where, if the textbox has error then the background property of the textbox will be changed to 'Red' and 'tooltip text’ will provide the error information.

The output will be as below:

image






About The Author

Mahesh Sabnis is a Microsoft MVP having over 18 years of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions). He also blogs regularly at DotNetCurry.com. Follow him on twitter @maheshdotnet

1 comment:

Unknown said...

How can the same validation be done with combobox? Any earlier reponse would be highly appreciated.