稳扎稳打Silverlight(51) - 4.0绑定之数据验证IDataErrorInfo, INotifyDataErrorInfo
稳扎稳打Silverlight(51) - 4.0绑定之数据验证IDataErrorInfo, INotifyDataErrorInfo
作者:webabcd
介绍
Silverlight 4.0 数据验证:
- IDataErrorInfo - 对数据实体类提供自定义验证支持。.NET Framework 也有此接口,可以方便移植
- INotifyDataErrorInfo - 对数据实体类提供自定义验证支持,比 IDataErrorInfo 功能更强大。INotifyDataErrorInfo 支持异步验证,这就意味着其可以通过验证方法调用 Web 服务和用回调方法更新错误集合来添加服务器端验证
在线DEMO
http://www.cnblogs.com/webabcd/archive/2010/08/09/1795417.html
示例
1、演示 IDataErrorInfo 的应用
IDataErrorInfoModel.cs
代码
/*
* IDataErrorInfo - 对数据实体类提供自定义验证支持。.NET Framework 也有此接口,可以方便移植
* string Error - 获取对象的验证错误信息
* string this[string columnName] - 获取对象的指定字段的验证错误信息
*/
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Silverlight40.Binding
{
public class IDataErrorInfoModel : System.ComponentModel.IDataErrorInfo
{
// 验证错误的提示信息
private const string ID_ERROR = "id 不能小于 10";
private const string NAME_ERROR = "name 不能包含空格";
private const string NAME_WARNING = "name 不能小于 5 个字符";
// 用于保存验证错误信息。key 保存所验证的字段名称;value 保存对应的字段的验证错误信息列表
private Dictionary<String, List<String>> errors = new Dictionary<string, List<string>>();
private int _id;
[Display(Name = "标识")]
public int Id
{
get { return _id; }
set
{
if (value > 1000)
throw new Exception("太大了");
if (IsIdValid(value) && _id != value)
_id = value;
}
}
private string _name;
[Display(Name = "名称")]
public string Name
{
get { return _name; }
set
{
if (IsNameValid(value) && _name != value)
_name = value;
}
}
public bool IsIdValid(int value)
{
bool isValid = true;
if (value < 10)
{
AddError("Id", ID_ERROR);
isValid = false;
}
else
{
RemoveError("Id", ID_ERROR);
}
return isValid;
}
public bool IsNameValid(string value)
{
bool isValid = true;
if (value.Contains(" "))
{
AddError("Name", NAME_ERROR);
isValid = false;
}
else
{
RemoveError("Name", NAME_ERROR);
}
if (value.Length < 5)
{
AddError("Name", NAME_WARNING);
isValid = false;
}
else
{
RemoveError("Name", NAME_WARNING);
}
return isValid;
}
public void AddError(string propertyName, string error)
{
if (!errors.ContainsKey(propertyName))
errors[propertyName] = new List<string>();
if (!errors[propertyName].Contains(error))
errors[propertyName].Add(error);
}
public void RemoveError(string propertyName, string error)
{
if (errors.ContainsKey(propertyName) && errors[propertyName].Contains(error))
{
errors[propertyName].Remove(error);
if (errors[propertyName].Count == 0)
errors.Remove(propertyName);
}
}
public string Error
{
get { return errors.Count > 0 ? "有验证错误" : "没有验证错误"; }
}
public string this[string propertyName]
{
get
{
if (errors.ContainsKey(propertyName))
return string.Join(Environment.NewLine, errors[propertyName]);
else
return null;
}
}
}
}
* IDataErrorInfo - 对数据实体类提供自定义验证支持。.NET Framework 也有此接口,可以方便移植
* string Error - 获取对象的验证错误信息
* string this[string columnName] - 获取对象的指定字段的验证错误信息
*/
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Silverlight40.Binding
{
public class IDataErrorInfoModel : System.ComponentModel.IDataErrorInfo
{
// 验证错误的提示信息
private const string ID_ERROR = "id 不能小于 10";
private const string NAME_ERROR = "name 不能包含空格";
private const string NAME_WARNING = "name 不能小于 5 个字符";
// 用于保存验证错误信息。key 保存所验证的字段名称;value 保存对应的字段的验证错误信息列表
private Dictionary<String, List<String>> errors = new Dictionary<string, List<string>>();
private int _id;
[Display(Name = "标识")]
public int Id
{
get { return _id; }
set
{
if (value > 1000)
throw new Exception("太大了");
if (IsIdValid(value) && _id != value)
_id = value;
}
}
private string _name;
[Display(Name = "名称")]
public string Name
{
get { return _name; }
set
{
if (IsNameValid(value) && _name != value)
_name = value;
}
}
public bool IsIdValid(int value)
{
bool isValid = true;
if (value < 10)
{
AddError("Id", ID_ERROR);
isValid = false;
}
else
{
RemoveError("Id", ID_ERROR);
}
return isValid;
}
public bool IsNameValid(string value)
{
bool isValid = true;
if (value.Contains(" "))
{
AddError("Name", NAME_ERROR);
isValid = false;
}
else
{
RemoveError("Name", NAME_ERROR);
}
if (value.Length < 5)
{
AddError("Name", NAME_WARNING);
isValid = false;
}
else
{
RemoveError("Name", NAME_WARNING);
}
return isValid;
}
public void AddError(string propertyName, string error)
{
if (!errors.ContainsKey(propertyName))
errors[propertyName] = new List<string>();
if (!errors[propertyName].Contains(error))
errors[propertyName].Add(error);
}
public void RemoveError(string propertyName, string error)
{
if (errors.ContainsKey(propertyName) && errors[propertyName].Contains(error))
{
errors[propertyName].Remove(error);
if (errors[propertyName].Count == 0)
errors.Remove(propertyName);
}
}
public string Error
{
get { return errors.Count > 0 ? "有验证错误" : "没有验证错误"; }
}
public string this[string propertyName]
{
get
{
if (errors.ContainsKey(propertyName))
return string.Join(Environment.NewLine, errors[propertyName]);
else
return null;
}
}
}
}
IDataErrorInfo.xaml
代码
<navigation:Page x:Class="Silverlight40.Binding.IDataErrorInfo"
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:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
Title="IDataErrorInfo Page">
<Grid x:Name="LayoutRoot">
<StackPanel HorizontalAlignment="Left">
<sdk:ValidationSummary Margin="3">
<sdk:ValidationSummary.Header>
错误列表:
</sdk:ValidationSummary.Header>
</sdk:ValidationSummary>
<!--
ValidatesOnExceptions - 指定绑定引擎是否报告验证过程中的异常信息
ValidatesOnDataErrors - 指定绑定引擎是否报告绑定数据实体上的 IDataErrorInfo 所实现的验证错误信息(通过 IDataErrorInfo 的 this[string columnName] 获取验证错误信息)
NotifyOnValidationError - 当出现验证错误时是否触发 BindingValidationError 事件
-->
<StackPanel Orientation="Horizontal">
<sdk:Label Target="{Binding ElementName=txtId}" />
<TextBox Name="txtId" Text="{Binding Id, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" KeyDown="txtId_KeyDown"/>
<sdk:DescriptionViewer Description="id 不能小于 10"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<sdk:Label Target="{Binding ElementName=txtName}"/>
<TextBox Name="txtName" Text="{Binding Name, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" KeyDown="txtName_KeyDown"/>
<sdk:DescriptionViewer Description="name 不能包含空格且 name 不能小于 5 个字符"/>
</StackPanel>
<Button Name="btnSubmit" Content="获取验证信息" Click="btnSubmit_Click" />
</StackPanel>
</Grid>
</navigation:Page>
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:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
Title="IDataErrorInfo Page">
<Grid x:Name="LayoutRoot">
<StackPanel HorizontalAlignment="Left">
<sdk:ValidationSummary Margin="3">
<sdk:ValidationSummary.Header>
错误列表:
</sdk:ValidationSummary.Header>
</sdk:ValidationSummary>
<!--
ValidatesOnExceptions - 指定绑定引擎是否报告验证过程中的异常信息
ValidatesOnDataErrors - 指定绑定引擎是否报告绑定数据实体上的 IDataErrorInfo 所实现的验证错误信息(通过 IDataErrorInfo 的 this[string columnName] 获取验证错误信息)
NotifyOnValidationError - 当出现验证错误时是否触发 BindingValidationError 事件
-->
<StackPanel Orientation="Horizontal">
<sdk:Label Target="{Binding ElementName=txtId}" />
<TextBox Name="txtId" Text="{Binding Id, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" KeyDown="txtId_KeyDown"/>
<sdk:DescriptionViewer Description="id 不能小于 10"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<sdk:Label Target="{Binding ElementName=txtName}"/>
<TextBox Name="txtName" Text="{Binding Name, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" KeyDown="txtName_KeyDown"/>
<sdk:DescriptionViewer Description="name 不能包含空格且 name 不能小于 5 个字符"/>
</StackPanel>
<Button Name="btnSubmit" Content="获取验证信息" Click="btnSubmit_Click" />
</StackPanel>
</Grid>
</navigation:Page>
IDataErrorInfo.xaml.cs
代码
/*
* 通过绑定实现了 IDataErrorInfo 接口的实体类来实现自定义数据验证功能
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
namespace Silverlight40.Binding
{
public partial class IDataErrorInfo : Page
{
IDataErrorInfoModel _model;
public IDataErrorInfo()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
_model = new IDataErrorInfoModel() { Id = 100, Name = "webabcd" };
LayoutRoot.DataContext = _model;
// BindingValidationError - 当有数据验证错误时所触发的事件。绑定时需要设置 NotifyOnValidationError=True
txtId.BindingValidationError += (x, y) => { MessageBox.Show(y.Error.ErrorContent.ToString()); };
txtName.BindingValidationError += (x, y) => { MessageBox.Show(y.Error.ErrorContent.ToString()); };
}
private void txtId_KeyDown(object sender, KeyEventArgs e)
{
// 注:
// BindingValidationError 事件只有在控件失去焦点才会被触发
// 如果需要在控件没失去焦点的情况下产生验证效果,那么可以通过调用 BindingExpression.UpdateSource() 方法来实现
// FrameworkElement.GetBindingExpression(DependencyProperty dp) - 获取 FrameworkElement 的指定属性上的绑定信息
// BindingExpression.UpdateSource() - 将当前绑定信息立即发送到绑定方式为 TwoWay 的属性上
if (e.Key == System.Windows.Input.Key.Enter)
txtId.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
private void txtName_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Enter)
txtName.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
private void btnSubmit_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("验证信息:" + _model.Error);
}
}
}
* 通过绑定实现了 IDataErrorInfo 接口的实体类来实现自定义数据验证功能
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
namespace Silverlight40.Binding
{
public partial class IDataErrorInfo : Page
{
IDataErrorInfoModel _model;
public IDataErrorInfo()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
_model = new IDataErrorInfoModel() { Id = 100, Name = "webabcd" };
LayoutRoot.DataContext = _model;
// BindingValidationError - 当有数据验证错误时所触发的事件。绑定时需要设置 NotifyOnValidationError=True
txtId.BindingValidationError += (x, y) => { MessageBox.Show(y.Error.ErrorContent.ToString()); };
txtName.BindingValidationError += (x, y) => { MessageBox.Show(y.Error.ErrorContent.ToString()); };
}
private void txtId_KeyDown(object sender, KeyEventArgs e)
{
// 注:
// BindingValidationError 事件只有在控件失去焦点才会被触发
// 如果需要在控件没失去焦点的情况下产生验证效果,那么可以通过调用 BindingExpression.UpdateSource() 方法来实现
// FrameworkElement.GetBindingExpression(DependencyProperty dp) - 获取 FrameworkElement 的指定属性上的绑定信息
// BindingExpression.UpdateSource() - 将当前绑定信息立即发送到绑定方式为 TwoWay 的属性上
if (e.Key == System.Windows.Input.Key.Enter)
txtId.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
private void txtName_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Enter)
txtName.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
private void btnSubmit_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("验证信息:" + _model.Error);
}
}
}
2、演示 INotifyDataErrorInfo 的应用
INotifyDataErrorInfoModel.cs
代码
/*
* INotifyDataErrorInfo - 对数据实体类提供自定义验证支持,比 IDataErrorInfo 功能更强大。INotifyDataErrorInfo 支持异步验证,这就意味着其可以通过验证方法调用 Web 服务和用回调方法更新错误集合来添加服务器端验证
* bool HasErrors - 对象是否有验证错误信息
* event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged - 当对象的验证错误信息发生改变时所触发的事件
* IEnumerable GetErrors(string propertyName) - 获取对象的指定字段的验证错误信息
*/
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
namespace Silverlight40.Binding
{
public class INotifyDataErrorInfoModel : System.ComponentModel.INotifyDataErrorInfo
{
// 验证错误的提示信息
private const string ID_ERROR = "id 不能小于 10";
private const string NAME_ERROR = "name 不能包含空格";
private const string NAME_WARNING = "name 不能小于 5 个字符";
// 用于保存验证错误信息。key 保存所验证的字段名称;value 保存对应的字段的验证错误信息列表
private Dictionary<String, List<String>> errors = new Dictionary<string, List<string>>();
private int _id;
[Display(Name = "标识")]
public int Id
{
get { return _id; }
set
{
if (value > 1000)
throw new Exception("太大了");
if (IsIdValid(value) && _id != value)
_id = value;
}
}
private string _name;
[Display(Name = "名称")]
public string Name
{
get { return _name; }
set
{
if (IsNameValid(value) && _name != value)
_name = value;
}
}
public bool IsIdValid(int value)
{
bool isValid = true;
if (value < 10)
{
AddError("Id", ID_ERROR);
isValid = false;
}
else
{
RemoveError("Id", ID_ERROR);
}
return isValid;
}
public bool IsNameValid(string value)
{
bool isValid = true;
if (value.Contains(" "))
{
AddError("Name", NAME_ERROR);
isValid = false;
}
else
{
RemoveError("Name", NAME_ERROR);
}
if (value.Length < 5)
{
AddError("Name", NAME_WARNING);
isValid = false;
}
else
{
RemoveError("Name", NAME_WARNING);
}
return isValid;
}
public void AddError(string propertyName, string error)
{
if (!errors.ContainsKey(propertyName))
errors[propertyName] = new List<string>();
if (!errors[propertyName].Contains(error))
{
errors[propertyName].Add(error);
RaiseErrorsChanged(propertyName);
}
}
public void RemoveError(string propertyName, string error)
{
if (errors.ContainsKey(propertyName) && errors[propertyName].Contains(error))
{
errors[propertyName].Remove(error);
if (errors[propertyName].Count == 0)
errors.Remove(propertyName);
RaiseErrorsChanged(propertyName);
}
}
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public void RaiseErrorsChanged(string propertyName)
{
if (ErrorsChanged != null)
ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));
}
public System.Collections.IEnumerable GetErrors(string propertyName)
{
if (errors.ContainsKey(propertyName))
return errors[propertyName];
else
return null;
}
public bool HasErrors
{
get { return errors.Count > 0; }
}
}
}
* INotifyDataErrorInfo - 对数据实体类提供自定义验证支持,比 IDataErrorInfo 功能更强大。INotifyDataErrorInfo 支持异步验证,这就意味着其可以通过验证方法调用 Web 服务和用回调方法更新错误集合来添加服务器端验证
* bool HasErrors - 对象是否有验证错误信息
* event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged - 当对象的验证错误信息发生改变时所触发的事件
* IEnumerable GetErrors(string propertyName) - 获取对象的指定字段的验证错误信息
*/
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
namespace Silverlight40.Binding
{
public class INotifyDataErrorInfoModel : System.ComponentModel.INotifyDataErrorInfo
{
// 验证错误的提示信息
private const string ID_ERROR = "id 不能小于 10";
private const string NAME_ERROR = "name 不能包含空格";
private const string NAME_WARNING = "name 不能小于 5 个字符";
// 用于保存验证错误信息。key 保存所验证的字段名称;value 保存对应的字段的验证错误信息列表
private Dictionary<String, List<String>> errors = new Dictionary<string, List<string>>();
private int _id;
[Display(Name = "标识")]
public int Id
{
get { return _id; }
set
{
if (value > 1000)
throw new Exception("太大了");
if (IsIdValid(value) && _id != value)
_id = value;
}
}
private string _name;
[Display(Name = "名称")]
public string Name
{
get { return _name; }
set
{
if (IsNameValid(value) && _name != value)
_name = value;
}
}
public bool IsIdValid(int value)
{
bool isValid = true;
if (value < 10)
{
AddError("Id", ID_ERROR);
isValid = false;
}
else
{
RemoveError("Id", ID_ERROR);
}
return isValid;
}
public bool IsNameValid(string value)
{
bool isValid = true;
if (value.Contains(" "))
{
AddError("Name", NAME_ERROR);
isValid = false;
}
else
{
RemoveError("Name", NAME_ERROR);
}
if (value.Length < 5)
{
AddError("Name", NAME_WARNING);
isValid = false;
}
else
{
RemoveError("Name", NAME_WARNING);
}
return isValid;
}
public void AddError(string propertyName, string error)
{
if (!errors.ContainsKey(propertyName))
errors[propertyName] = new List<string>();
if (!errors[propertyName].Contains(error))
{
errors[propertyName].Add(error);
RaiseErrorsChanged(propertyName);
}
}
public void RemoveError(string propertyName, string error)
{
if (errors.ContainsKey(propertyName) && errors[propertyName].Contains(error))
{
errors[propertyName].Remove(error);
if (errors[propertyName].Count == 0)
errors.Remove(propertyName);
RaiseErrorsChanged(propertyName);
}
}
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public void RaiseErrorsChanged(string propertyName)
{
if (ErrorsChanged != null)
ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));
}
public System.Collections.IEnumerable GetErrors(string propertyName)
{
if (errors.ContainsKey(propertyName))
return errors[propertyName];
else
return null;
}
public bool HasErrors
{
get { return errors.Count > 0; }
}
}
}
INotifyDataErrorInfo.xaml
代码
<navigation:Page x:Class="Silverlight40.Binding.INotifyDataErrorInfo"
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:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
Title="INotifyDataErrorInfo Page">
<Grid x:Name="LayoutRoot">
<StackPanel HorizontalAlignment="Left">
<sdk:ValidationSummary Margin="3">
<sdk:ValidationSummary.Header>
错误列表:
</sdk:ValidationSummary.Header>
</sdk:ValidationSummary>
<!--
ValidatesOnExceptions - 指定绑定引擎是否报告验证过程中的异常信息
NotifyOnValidationError - 当出现验证错误时是否触发 BindingValidationError 事件
-->
<StackPanel Orientation="Horizontal">
<sdk:Label Target="{Binding ElementName=txtId}" />
<TextBox Name="txtId" Text="{Binding Id, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}" KeyDown="txtId_KeyDown"/>
<sdk:DescriptionViewer Description="id 不能小于 10"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<sdk:Label Target="{Binding ElementName=txtName}"/>
<TextBox Name="txtName" Text="{Binding Name, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}" KeyDown="txtName_KeyDown"/>
<sdk:DescriptionViewer Description="name 不能包含空格且 name 不能小于 5 个字符"/>
</StackPanel>
<Button Name="btnSubmit" Content="是否有验证错误" Click="btnSubmit_Click" />
</StackPanel>
</Grid>
</navigation:Page>
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:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
Title="INotifyDataErrorInfo Page">
<Grid x:Name="LayoutRoot">
<StackPanel HorizontalAlignment="Left">
<sdk:ValidationSummary Margin="3">
<sdk:ValidationSummary.Header>
错误列表:
</sdk:ValidationSummary.Header>
</sdk:ValidationSummary>
<!--
ValidatesOnExceptions - 指定绑定引擎是否报告验证过程中的异常信息
NotifyOnValidationError - 当出现验证错误时是否触发 BindingValidationError 事件
-->
<StackPanel Orientation="Horizontal">
<sdk:Label Target="{Binding ElementName=txtId}" />
<TextBox Name="txtId" Text="{Binding Id, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}" KeyDown="txtId_KeyDown"/>
<sdk:DescriptionViewer Description="id 不能小于 10"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<sdk:Label Target="{Binding ElementName=txtName}"/>
<TextBox Name="txtName" Text="{Binding Name, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}" KeyDown="txtName_KeyDown"/>
<sdk:DescriptionViewer Description="name 不能包含空格且 name 不能小于 5 个字符"/>
</StackPanel>
<Button Name="btnSubmit" Content="是否有验证错误" Click="btnSubmit_Click" />
</StackPanel>
</Grid>
</navigation:Page>
INotifyDataErrorInfo.xaml.cs
代码
/*
* 通过绑定实现了 INotifyDataErrorInfo 接口的实体类来实现自定义数据验证功能
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
namespace Silverlight40.Binding
{
public partial class INotifyDataErrorInfo : Page
{
INotifyDataErrorInfoModel _model;
public INotifyDataErrorInfo()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
_model = new INotifyDataErrorInfoModel() { Id = 100, Name = "webabcd" };
LayoutRoot.DataContext = _model;
// BindingValidationError - 当有数据验证错误时所触发的事件。绑定时需要设置 NotifyOnValidationError=True
txtId.BindingValidationError += (x, y) => { MessageBox.Show(y.Error.ErrorContent.ToString()); };
txtName.BindingValidationError += (x, y) => { MessageBox.Show(y.Error.ErrorContent.ToString()); };
}
private void txtId_KeyDown(object sender, KeyEventArgs e)
{
// 注:
// BindingValidationError 事件只有在控件失去焦点才会被触发
// 如果需要在控件没失去焦点的情况下产生验证效果,那么可以通过调用 BindingExpression.UpdateSource() 方法来实现
// FrameworkElement.GetBindingExpression(DependencyProperty dp) - 获取 FrameworkElement 的指定属性上的绑定信息
// BindingExpression.UpdateSource() - 将当前绑定信息立即发送到绑定方式为 TwoWay 的属性上
if (e.Key == System.Windows.Input.Key.Enter)
txtId.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
private void txtName_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Enter)
txtName.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
private void btnSubmit_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("是否有验证错误:" + _model.HasErrors.ToString());
}
}
}
* 通过绑定实现了 INotifyDataErrorInfo 接口的实体类来实现自定义数据验证功能
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
namespace Silverlight40.Binding
{
public partial class INotifyDataErrorInfo : Page
{
INotifyDataErrorInfoModel _model;
public INotifyDataErrorInfo()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
_model = new INotifyDataErrorInfoModel() { Id = 100, Name = "webabcd" };
LayoutRoot.DataContext = _model;
// BindingValidationError - 当有数据验证错误时所触发的事件。绑定时需要设置 NotifyOnValidationError=True
txtId.BindingValidationError += (x, y) => { MessageBox.Show(y.Error.ErrorContent.ToString()); };
txtName.BindingValidationError += (x, y) => { MessageBox.Show(y.Error.ErrorContent.ToString()); };
}
private void txtId_KeyDown(object sender, KeyEventArgs e)
{
// 注:
// BindingValidationError 事件只有在控件失去焦点才会被触发
// 如果需要在控件没失去焦点的情况下产生验证效果,那么可以通过调用 BindingExpression.UpdateSource() 方法来实现
// FrameworkElement.GetBindingExpression(DependencyProperty dp) - 获取 FrameworkElement 的指定属性上的绑定信息
// BindingExpression.UpdateSource() - 将当前绑定信息立即发送到绑定方式为 TwoWay 的属性上
if (e.Key == System.Windows.Input.Key.Enter)
txtId.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
private void txtName_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Enter)
txtName.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
private void btnSubmit_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("是否有验证错误:" + _model.HasErrors.ToString());
}
}
}
注:
Silverlight 2.0 下的绑定及数据验证:http://www.cnblogs.com/webabcd/archive/2008/11/20/1337190.html
Silverlight 3.0 下的绑定:http://www.cnblogs.com/webabcd/archive/2009/09/03/1559240.html
Silverlight 3.0 下的数据验证(依赖 DataAnnotations):http://www.cnblogs.com/webabcd/archive/2009/08/10/1542663.html
OK
[源码下载]