在此,我们将利用上面两篇文章所打好的基础来实现Silverlight在双向绑定由目标到数据源更新数据的过程中,对数据的校验实现。
参阅MSDN我们知道,当遇到以下两种情况时,Silverlight将会报告数据验证错误。
1、转换绑定数据时抛出异常。
2、绑定数据源对象的set访问器抛出异常。
下面,开始我们的示例部分。
在"SilverLight学习笔记--Silverlight之数据绑定初探 "一文中我们探讨了Silverlight界面控件的数据绑定,
在"SilverLight学习笔记--Silverlight中INotifyPropertyChanged 接口在数据绑定中的使用 "一文中我们探讨了如何使用INotifyPropertyChanged 接口实现数据绑定的同步和更新。
在此,我们将利用上面两篇文章所打好的基础来实现Silverlight在双向绑定由目标到数据源更新数据的过程中,对数据的校验实现。
参阅MSDN我们知道,当遇到以下两种情况时,Silverlight将会报告数据验证错误。
1、转换绑定数据时抛出异常。
2、绑定数据源对象的set访问器抛出异常。
为了获取这些数据验证错误信息,必须将绑定对象的ValidatesOnExceptions属性和NotifyOnValidationError属性设为True。
如本例将用到的TextBox控件定义
<TextBox x:Name="txtBxScore" FontFamily="Georgia" FontSize="18" HorizontalAlignment="Left"
VerticalAlignment="Bottom" Margin="10" Width="150" Height="40"
TextWrapping="Wrap"
Text="{Binding ClassScore, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnExceptions=True}"
BindingValidationError="txtBxScore_BindingValidationError"/>
对上面的定义说明如下:
i、将ValidatesOnExceptions属性设为True可以让绑定引擎在异常抛出时产生一个验证错误信息。
ii、将NotifyOnValidationError属性设为true可以通知绑定引擎当遇到验证错误时,触发BindingValidationError事件(即上面的BindingValidationError="txtBxClassName_BindingValidationError" )。
iii、对于BindingValidationError事件,可以为目标对象或者其父节点创建一个事件响应函数,来捕获该事件,从而对数据绑定出现异常的情况做出应对。
iv、BindingValidationError事件是一个路由事件,因此,不必让真正产生异常的那个对象处理BindingValidationError事件。BindingValidationError事件触发后将会向上冒泡传递,直至它被处理,所以可以在父节点上添加事件响应函数(在本例中,可以在存放TextBox控件的StackPanel控件中设置BindingValidationError相关事件)。
下面,开始我们的示例部分。
还是照常,先新建一个Silverlight应用程序命名为:SLValidation。
在此程序,我们将建立一个课程成绩输入界面,Page.xaml代码如下:
Code
<UserControl x:Class="SLValidation.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="500" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel>
<TextBlock Text="Silverlight数据验证示例" FontSize="20" TextAlignment="Center" Height="30" Foreground="Green" Margin="10"></TextBlock>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="请输入课程名" FontSize="16" TextAlignment="Center" Height="30" Foreground="Blue"></TextBlock>
<TextBox x:Name="txtBxClassName" FontFamily="Georgia" FontSize="18" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="10" Width="150" Height="40"
TextWrapping="Wrap" Text="{Binding ClassName, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnExceptions=True}"
BindingValidationError="txtBxClassName_BindingValidationError" />
<TextBlock x:Name="tbClassNameMsg" Text="" Width="120" FontSize="12" TextAlignment="Center" Height="30" Foreground="Red" ></TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="请输入成绩值" FontSize="16" TextAlignment="Center" Height="30" Foreground="Blue"></TextBlock>
<TextBox x:Name="txtBxScore" FontFamily="Georgia" FontSize="18" HorizontalAlignment="Left"
VerticalAlignment="Bottom" Margin="10" Width="150" Height="40"
TextWrapping="Wrap"
Text="{Binding ClassScore, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnExceptions=True}"
BindingValidationError="txtBxScore_BindingValidationError"/>
<TextBlock x:Name="tbClassScoreMsg" Text="" Width="120" FontSize="12" TextAlignment="Center" Height="30" Foreground="Red" ></TextBlock>
</StackPanel>
<Button x:Name="btnOK" Width="250" Height="50" Content="确定输入" FontSize="18" Foreground="Green" Click="btnOK_Click"></Button>
</StackPanel>
</Grid>
</UserControl>
界面如下图:
其功能是:
在课程文本框中输入课程名,如果此处为空,则报错,并把背景显示为红色。
在成绩文本框中输入成绩值 ,如果此处输入的整数在0和100范围之外,则报错,并把背景显示为红色。
1、前端界面的控件属性设置要求
注意,在界面代码中的两个TextBox控件的设置如下:
<TextBox x:Name="txtBxClassName" FontFamily="Georgia" FontSize="18" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="10" Width="150" Height="40"
TextWrapping="Wrap" Text="{Binding ClassName, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnExceptions=True}"
BindingValidationError="txtBxClassName_BindingValidationError" />
<TextBox x:Name="txtBxScore" FontFamily="Georgia" FontSize="18" HorizontalAlignment="Left"
VerticalAlignment="Bottom" Margin="10" Width="150" Height="40"
TextWrapping="Wrap"
Text="{Binding ClassScore, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnExceptions=True}"
BindingValidationError="txtBxScore_BindingValidationError"/>
在它们的属性设置中,我们需要把ValidatesOnExceptions属性和NotifyOnValidationError属性设为True,并各自设置它们的BindingValidationError事件。此事件的具体操作在后台代码中实现。
并且,我们还需要把数据绑定的Mode设置为双向绑定 TwoWay,因为只有如此绑定才能实现绑定校验。
2、数据源定义的相关要求
然后创建我们将要实施数据绑定所用到的数据源类,命名为Score,代码如下:
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.ComponentModel;//引入此空间后才能使用INotifyPropertyChanged接口
namespace SLValidation
{
public class Score:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int _classScore;
private string _className;
定义ClassScore属性#region 定义ClassScore属性
public int ClassScore
{
get { return _classScore; }
set
{
if (!ValideScore(value))
{
throw new Exception("成绩必须介于0到100之间!");
}
_classScore = value;
NotifyPropertyChange("ClassScore");
}
}
#endregion
定义ClassName属性#region 定义ClassName属性
public string ClassName
{
get { return _className; }
set
{
if (!ValideClassName(value))
{
throw new Exception("请输入课程名称!");
}
_className = value;
NotifyPropertyChange("ClassName");
}
}
#endregion
校验Score属性#region 校验Score属性
private bool ValideScore(int scoreInt)
{
if(scoreInt< 0 ||scoreInt> 100)
{
return false;
}
else
{
return true;
}
}
#endregion
校验ClassName属性#region 校验ClassName属性
private bool ValideClassName(string classNameStr)
{
if (classNameStr=="")
{
return false;
}
else
{
return true;
}
}
#endregion
实现INotifyPropertyChanged接口#region 实现INotifyPropertyChanged接口
private void NotifyPropertyChange(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
注意:数据源类的定义说明如下:
i、它必须继承自INotifyPropertyChanged接口。
ii、在它的属性的Set代码段中需要定义如何进行校验以及在何种情况下抛出异常。
建立好界面和定义数据源后程序如下图:
3、后台代码的数据绑定及相关处理
Page.xaml.cs全部代码如下:
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;
namespace SLValidation
{
public partial class Page : UserControl
{
Score sc = new Score();
public Page()
{
InitializeComponent();
Loaded+=new RoutedEventHandler(Page_Loaded);
}
初始化数据源并绑定数据#region 初始化数据源并绑定数据
private void Page_Loaded(object sender, RoutedEventArgs e)
{
sc.ClassScore = 60;
sc.ClassName = "Mandarian";
this.txtBxScore.DataContext = sc;
this.txtBxClassName.DataContext = sc;
}
#endregion
成绩绑定的相关BindingValidationError事件处理#region 成绩绑定的相关BindingValidationError事件处理
private void txtBxScore_BindingValidationError(object sender, ValidationErrorEventArgs e)
{
if (e.Action == ValidationErrorEventAction.Added)
{
this.txtBxScore.Background = new SolidColorBrush(Colors.Red);
//this.tbClassScoreMsg.Text = e.Error.Exception.ToString();
this.tbClassScoreMsg.Text = "成绩值应该介于0到100之间!";
}
else if (e.Action == ValidationErrorEventAction.Removed)
{
this.txtBxScore.Background = new SolidColorBrush(Colors.White);
this.tbClassScoreMsg.Text = "";
}
}
#endregion
课程名绑定的相关BindingValidationError事件处理#region 课程名绑定的相关BindingValidationError事件处理
private void txtBxClassName_BindingValidationError(object sender, ValidationErrorEventArgs e)
{
if (e.Action == ValidationErrorEventAction.Added)
{
this.txtBxClassName.Background = new SolidColorBrush(Colors.Red);
//this.tbClassNameMsg.Text = e.Error.Exception.ToString();
this.tbClassNameMsg.Text = "课程名称输入不能为空!";
}
else if (e.Action == ValidationErrorEventAction.Removed)
{
this.txtBxClassName.Background = new SolidColorBrush(Colors.White);
this.tbClassNameMsg.Text = "";
}
}
#endregion
private void btnOK_Click(object sender, RoutedEventArgs e)
{
//加此按钮的作用是激发数据绑定校验
}
}
}
注意:我们需要在此处加入对数据绑定异常的处理代码即BindingValidationError事件代码。
在绑定出错的情况下,程序显示如下图:
前往:Silverlight学习笔记清单
本文程序在Silverlight2.0和VS2008环境中调试通过。本文参照了部分网络资料,希望能够抛砖引玉,大家共同学习。
(转载本文请注明出处)