常用类

类名 介绍
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. 关于GDPR,你需要了解的的5件事

    GDPR要求组织确保对用户数据进行良好的保护,而不是滥用,使用户获得知情同意,并且违规行为将受到巨额罚款. 欧盟通用数据保护条例(GDPR)于2018年5月25日开始执行.然而直到如今,还是有不少人对 ...

  2. volatile实现原理--为什么实现了可见性却不能保证原子性

    本篇文章我们来解决一个问题  这也是面试面的比较多的问题,进阶阶段(高级)一般都会问到. volatile变量怎么保证可见性  为什么在并发情况下无法保证原子性? 比较懒了  摘了一段JVM原理的片段 ...

  3. redis系列:分布式锁

    redis系列:分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...

  4. 智能BPOS小票模板字体的使用

    关于伯俊智能BPOS零售小票模板的设置,常用字体"黑体"."宋体"."Arial"这几个字体,在设置的时候看似没有问题, 但是在正真使用打印 ...

  5. 使用纯 CSS 实现滚动阴影效果

    开门见山,有这样一种非常常见的情况,对于一些可滚动的元素而言.通常在滚动的时候会给垂直于滚动的一侧添加一个阴影,用于表明当前有元素被滚动给该滚出了可视区域,类似这样: 可以看到,在滚动的过程中,会出现 ...

  6. ES6 class类 静态方法及类的继承

    一.class类 ES6之前都是定义函数以及函数的原型对象实现类型, 如果想要实现共享构造函数成员,可以用prototype来共享实现 ES6出现之后,使用class类的概念来实现原型的继承 二,静态 ...

  7. Mybatis-plus的使用步骤

    Mybatis-plus的简单使用步骤 花开堪折直需折,莫待无花空折枝 导入依赖 <dependency> <groupId>org.projectlombok</gro ...

  8. 【对线面试官】Java 反射&&动态代理

    // 抽象类,定义泛型<T> public abstract class BaseDao<T> { public BaseDao(){ Class clazz = this.g ...

  9. 安装SVN和汉化包及基本使用

    官网下载程序 和 下载汉化包. https://tortoisesvn.net/   注意SVN汉化包版本需要和SVN版本一致,否则是无效的. 一.下载 1.进入官网,点击downloads 2.点击 ...

  10. SpringBoot同时接收单个对象和List<object>参数

    最近做项目的有个需求,是把多个文件移动到另一个文件夹下,这需要把 新的文件夹id -- Long类型 多个文件的信息 -- List< Object > 类型 这两个参数传给后台,我的后台 ...