数据绑定-验证(二)

在数据绑定时,还有一项工做,就是数据的验证。ide

在上一篇博文中,文本框来显示person对象的年龄,咱们知道,由于年龄是数据,在输入非数字时,必定是不符合现实意义的。在WPF中,对数据的绑定,特别是双向绑定,数据目标属性更新数据源属性时,进行数据验证,道先,若是给一个绑定目标属性加入验证,必需用属性元素语法来达到目的,就是给Binding属性添加一个<Binding.ValudationRules>,再添加一个<ExceptionValidationRule>的子标签,同时把<Binding>标签的NotifyOnValidationError的属性设置成true,这样,后台的验证代码才起做用(由于默认状况下NotifyOnValidationError是 false)双向绑定

<TextBox Height="23" Margin="12,31,0,0" Name="textBox1" ;120" >orm

<TextBox.Text>对象

<Binding Path="Age" Mode="TwoWay" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged">继承

<Binding.ValidationRules>string

<ExceptionValidationRule>it

</ExceptionValidationRule>io

</Binding.ValidationRules>class

</Binding>后台

</TextBox.Text>

</TextBox>

上面XAML代码与下面代码功能相同:

Binding bd = new Binding("Age");

bd.Mode = BindingMode.TwoWay;

bd.NotifyOnValidationError = true;

bd.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;

ValidationRule vr = new ExceptionValidationRule();

bd.ValidationRules.Add(vr);

textBox1.SetBinding(TextBox.TextProperty, bd);

而后把验证失败后的执行操做代码,关联起来,以下:

Validation.AddErrorHandler(textBox1, valite);

//下面是验证失败后的代码。

public void valite(object sender, ValidationErrorEventArgs e)

{

if (e.Action == ValidationErrorEventAction.Added)

{

MessageBox.Show((string)e.Error.ErrorContent, "验¨|证?è错?¨a误¨?!ê?");

}

}

在验证数据时,咱们用的是系统自定义的验证类ValidationRule,这个类是个抽象类,目前的版本微软提供了两个子类来实现它,一个是ExceptionValidationRule,另外一个是DataErrorValidationRule,前者是捕获在绑定目标属性把数据更新回绑定源属性时的异常,后者是检查绑定源提供用户界面能够绑定的自定义错误信息。本例子中,用的是ExceptionValidationRule,实际上就是把一些非int类型的数值给person.Age赋值时,触发异常,ExceptionValidationRule就捕获到异常,从而经过Validation.AddErrorHandler来报出异常。

另外,即然ValidationRule是抽象类,ExceptionValidationRule和DataErrorValidationRule都是继承它来的,能不能咱们也定义一个类去继承ValidationRule,来完成本身的验证呢,答案是确定的,就拿上面的例子来讲Age,通常是在0到150之间(人的年龄通常没有负的,人的年龄指活的时长,也就是人最多活150岁,这个值已经至关对得起活着的人了),那就能够自定义一个类,继承ValidationRule,来实现这个年龄范围的业务。

首先来定义这个类:

public class ValidationAge:ValidationRule

{

public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)

{

int age;

if (!int.TryParse(value.ToString(), out age))

{

return new ValidationResult(false, "年龄类型不正确!");

}

else

{

if (age < 0 || age > 150)

{

return new ValidationResult(false, "不符合人类的年龄(0-150)!");

}

else

{

return new ValidationResult(true, null);

}

}

}

}

XAML代码以下:

<TextBox Height="23" Margin="12,31,0,0" Name="textBox1" ;120" >

<TextBox.Text>

<Binding Path="Age" Mode="TwoWay" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged">

<Binding.ValidationRules>

<m:ValidationAge>

</m:ValidationAge>

</Binding.ValidationRules>

</Binding>

</TextBox.Text>

</TextBox>

或用代码实现:

Binding bd = new Binding("Age");

bd.Mode = BindingMode.TwoWay;

bd.NotifyOnValidationError = true;

bd.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;

ValidationRule vr = new ValidationAge();

bd.ValidationRules.Add(vr);

textBox1.SetBinding(TextBox.TextProperty, bd);

若是抛开WPF绑定这个概念,上面所作的工做就是从UI的值往对象中回写的时候,若是不符合要求,就抛出异常,在 WinForm中,咱们一般是给类的属性设置这些验证,就是在Person类的Age属性Set访问器中验证Value的有效性,固然,这种作完在WPF中也有效,相经较之下,这种作法还较简单。其实WPF中的这种作法,本质是同样的,就在是调用Person类的Age的Set访问器前,加了一个验证。

还有一点要注意的是在验证方法valite中,ValidationErrorEventArgs参数有一个Action的属性,这个属性是个枚举值,有两个枚举值,Added和Removed,若是不做处理,当咱们输入一个非数字的值时,理所固然报错,但当咱们删除这个值时也报错,就是由于才望高验证的触发是验证值的改变,添加和删除(没有修改,由于修改是一个删除+添加的过程),因此为了不出来两次验证,就做了一下处理,只验证Action为Added的。

再有一点就是,若是绑定不作自定义验证VlidationAge,而是用ExceptionValidationRule,文本框与年龄绑定,由于年龄是整型,若是在文本框中输和e或E,都会转化成科学讲学法的,这点要注意。

相关文章
相关标签/搜索