常用类

类名 介绍
ValidationRule 所有自定义验证规则的基类。提供了让用户定义验证规则的入口。
ExceptionValidation 表示一个规则,该规则检查在绑定源属性更新过程中引发的异常。它是一个内置的规则,它检查在绑定源属性更新过程中引发的异常。
ValidationResult 数据验证结果的表现方式。ValidationRule对象的Validate方法执行完毕后通过ValidationResult来表示验证的结果。这里包含了错误信息—ErrorContent,数据是否有效—IsValid。ValidResult 为 ValidationResult 的有效实例。
ValidationError 表示一个验证错误,该错误在 ValidationRule 报告验证错误时由绑定引擎创建。

ExceptionValidationRule 验证

通过在某个 Binding 对象上设置 ValidatesOnExceptions 属性,如果源对象属性设置已修改的值的过程中引发异常,则抛出错误并为该 Binding 设置验证错误.


<StackPanel Orientation="Vertical" Margin="0,10,0,0" >
<StackPanel>
<Label Content="用户名" Target="{Binding ElementName=UserName}"/>
<TextBox Width="150">
<TextBox.Text>
<Binding Path="UserName" ValidatesOnExceptions="true",UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<ExceptionValidationRule></ExceptionValidationRule>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</StackPanel>
</StackPanel>

核心:
TextBox 绑定默认是LostFocus ,所以必须要设置UpdateSourceTrigger="PropertyChanged。不然只有在离开文本才会使用。
主要设置 ExceptionValidationRule,ValidatesOnExceptions=true不然不会触发.

说明:
它捕获任何位置发生的异常,包括当编辑的值不能转换成正确数据类型时发生异常、由属性设置器抛出的异常以及由值转换器抛出的异常,虽实现简单,但一般不使用这种方式。

ValidationRule 验证:

   <StackPanel>
<Label Content="用户名" Target="{Binding ElementName=UserName}"/>
<TextBox Width="150" >
<TextBox.Text>
<Binding Path="UserName" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors = "true">
<Binding.ValidationRules>
<app:RequiredRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</StackPanel>

继承ValidationRule重写ValidationResult 方法。

public class RequiredRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
if (value == null)
return new ValidationResult(false, "必填!");
if (string.IsNullOrEmpty(value.ToString()))
return new ValidationResult(false, "必填!");
return new ValidationResult(true, null);
}
}

样式:
一般TextBox需要重写TextBox框控件模板,本人在此推荐MaterialDesign
使用方式简单,不在此阐述。

实现效果:

优点:

相对来说,这种方式是比较不错的,独立性、复用性都很好,从松散耦合角度来说也是比较恰当的。
可以预先写好一系列的验证规则类,视图编码人员可以根据需求直接使用这些验证规则,服务端无需额外的处理。

缺点:

扩展性差,如果需要个性化反馈消息也需要额外扩展。不符合日益丰富的前端验证需求。

建议:封装自定义控件使用这个方式,松耦合。

IDataErrorInfo + DataAnnotations实现验证

在实际开发中,我们还经常使用 EF 等 ORM 来做数据访问层,Model 通常会由这个中间件自动生成(利用T4等代码生成工具)。而他们通常是 POCO 数据类型,这时候如何能把属性的校验特性加入其中呢。这时候, TypeDescriptor.AddProviderTransparent + AssociatedMetadataTypeTypeDescriptionProvider 可以派上用场,它可以实现在另一个类中增加对应校验特性来增强对原类型的元数据描述。按照这种思路,将上面的 Person 类分离成两个文件:第一个分离类,可以想象是中间件自动生成的 Model 类。第二个分离类中实现 IDataErrorInfo,并定义一个Metadata 类来增加校验特性。(EF CodeFirst 也可以使用这一思路)

这部分推荐阅读原文,原文出处:MVVM模式下的输入校验IDataErrorInfo + DataAnnotations

这可能会有两个问题:

  • 产生验证错误,验证后的数据仍然会更改数据源的值。
  • 如果系统出现异常,如成绩值输入12x,则系统不会显示错误,空间上的输入值也不会赋值到数据源。这种情况下,需要使用ExceptionValidationRule。

总结:按照使用优先级进行排序

IDataErrorInfo+DataAnnotation 进行组合验证,最为灵活复用性也高,MVVM推荐优先使用。

IDataErrorInfo验证,涉及较多判断语句,最好配合DataAnnotation 进行验证。

ValidationRule适合在用户控件或者自定义控件场合使用。

异常验证除了初始测试外,不推荐使用,虽然实现简单但是会影响性能。

最新文章

  1. 国内可用maven repository 配置
  2. Linux-eth0 eth0:1 和eth0.1关系、ifconfig以及虚拟IP实现介绍
  3. qwtplot3D安装及运行-----终结解决方案
  4. HDU4325--Flowers--树状数组,离散化
  5. SQL Server没有足够的内存继续执行程序 (mscorlib)的解决办法
  6. mysql之统一刷表
  7. dedecms调用日期格式化形式大全
  8. Java-Reflection反射-获取包括父类在内的所有字段
  9. CentOS 7.3.1611编译安装Nginx1.10.3+MySQL5.7.16+PHP7.1.2
  10. Spring JDBC SimpleJdbcCall类示例
  11. 第2课 C 到 C++ 的升级
  12. activeMQ Jms Demo
  13. redis常用配置参数解析
  14. JavaWeb请求中文乱码
  15. 用python实现按权重对N个数据进行选择
  16. ubuntu下telnet安装
  17. 1503: [NOI2004]郁闷的出纳员
  18. CentOS7 安装 PHP7.2
  19. hiho 1055 刷油漆 树形dp
  20. [Ramda] Pick and Omit Properties from Objects Using Ramda

热门文章

  1. java中根据后端返回的数据加载table列表
  2. 后台查询出来的list结果 在后台查询字典表切换 某些字段的内容
  3. MySQL-5.7.29-winx64解压缩版安装
  4. [leetcode350]Intersection of Two Arrays II求数组交集
  5. dp的冗余(选数类)
  6. ES快速开发,ElasticsearchRestTemplate基本使用以及ELK快速部署
  7. 记一次flask上传文件返回200前端却504的问题
  8. 【Java基础】面向对象上
  9. 【Redis3.0.x】NoSql 入门
  10. Linux调整lvm逻辑分区大小