常用类

类名 介绍
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适合在用户控件或者自定义控件场合使用。

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

WPF mvvm 验证,耗时两天的解决方案的更多相关文章

  1. WPF MVVM 验证

    WPF MVVM(Caliburn.Micro) 数据验证 书接前文 前文中仅是WPF验证中的一种,我们暂且称之为View端的验证(因为其验证规是写在Xaml文件中的). 还有一种我们称之为Model ...

  2. WPF MVVM从入门到精通8:数据验证

    原文:WPF MVVM从入门到精通8:数据验证 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通3:数据绑定 WPF M ...

  3. WPF MVVM(Caliburn.Micro) 数据验证

    书接前文 前文中仅是WPF验证中的一种,我们暂且称之为View端的验证(因为其验证规是写在Xaml文件中的). 还有一种我们称之为Model端验证,Model通过继承IDataErrorInfo接口来 ...

  4. .NET Core 3 WPF MVVM框架 Prism系列之命令

    本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的命令的用法 一.创建DelegateCommand命令 我们在上一篇.NET Core 3 WPF MVVM框架 Prism系列之 ...

  5. WPF MVVM使用prism4.1搭建

    WPF MVVM使用prism4.1搭建 MVVM即Model-View-ViewModel,MVVM模式与MVP(Model-View-Presenter)模式相似,主要目的是分离视图(View)和 ...

  6. WPF MVVM从入门到精通6:RadioButton等一对多控件的绑定

    原文:WPF MVVM从入门到精通6:RadioButton等一对多控件的绑定   WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM ...

  7. WPF MVVM从入门到精通5:PasswordBox的绑定

    原文:WPF MVVM从入门到精通5:PasswordBox的绑定   WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通 ...

  8. WPF MVVM从入门到精通4:命令和事件

    原文:WPF MVVM从入门到精通4:命令和事件   WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通3:数据绑定 WP ...

  9. WPF MVVM从入门到精通1:MVVM模式简介

    原文:WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通3:数据绑定 W ...

随机推荐

  1. 今天写了一个SSM小项目,运行之后,前端页面的CSS、js样式显示不出来,具体操作如下:

    因为SSM中我们设置了拦截器,拦截器会拦截CSS和JS,所有样式渲染不出来,在Web.xml中写上 1 <servlet-mapping> 2 <servlet-name>de ...

  2. druid监控

    1 @ConfigurationProperties(prefix = "spring.datasource") 2 @Bean 3 public DataSource druid ...

  3. 第十八章节 BJROBOT 安卓手机 APP 建地图【ROS全开源阿克曼转向智能网联无人驾驶车】

    1.把小车平放在地板上,用资料里的虚拟机,打开一个终端 ssh 过去主控端启动roslaunch znjrobotbringup.launch 2.在虚拟机端再打开一个终端,ssh 过去主控端启动ro ...

  4. keycloak集群化的思考

    目录 简介 keycloak中的集群 load balancing负载均衡 暴露客户端IP地址 sticky sessions 和 非sticky sessions shared databases ...

  5. 基于Jmeter实现Rocketmq消息发送

    在互联网企业技术架构中,MQ占据了越来越重要的地位.系统解耦.异步通信.削峰填谷.数据顺序保证等场景中,到处都能看到MQ的身影. 而测试工程师在工作中,也经常需要和mq打交道,比如构造测试数据,触发某 ...

  6. JVM-03

    目录 1.1 新生代垃圾收集器 1.1.1 Serial 垃圾收集器(单线程) 1.1.2 ParNew 垃圾收集器(多线程) 1.1.3 Parallel Scavenge 垃圾收集器(多线程) 2 ...

  7. 【分布式锁的演化】终章!手撸ZK分布式锁!

    前言 这应该是分布式锁演化的最后一个章节了,相信很多小伙伴们看完这个章节之后在应对高并发的情况下,如何保证线程安全心里肯定也会有谱了.在实际的项目中也可以参考一下老猫的github上的例子,当然代码没 ...

  8. xtrabackup 备份与恢复

    书上摘抄 ---深入浅出mysql 448页  grant reload on *.* to 'backup'@'localhost' identified by '123456'; grant re ...

  9. 【Oracle】10g查看trace生成文件位置及文件名称

    select  u_dump.value || '/' ||  db_name.value || '_ora_' ||  v$process.spid ||  nvl2(v$process.trace ...

  10. C#数组的 Length 和 Count()

    C#数组的 Length 和 Count() C# 数组中 Length 表示数组项的个数,是个属性.而 Count() 也是表示项的个数,是个方法,它的值和 Length 一样.但实际上严格地说, ...