对于WPF中的验证, View验证实现起来很简单, 可以通道 Validation.ErrorEvent 冒泡传递到View的逻辑树上, 只是, 通常这样做的情况下, 我们需要为View添加事件代码监听这类错误事件, 然后进行处理。

这样做可以说是非常简单, 但是这样的硬编码的, 基本上每个模块每个功能, 你都必不可少的为其进行重复的工作, 这是一项非常枯燥且无聊的体力活!

于是, 则考虑MVVM的架构中, 如何把这种模式传递到ViewModel中, 使得前端的验证, 对于ViewModel仍然有效。

实现的原理, 如图所示:

在此之前, 对于View前端验证需要做的一些操作步骤,

  • 1.为验证的属性添加自定义验证类
  • 2.设置验证错误的通知属性 NotifyOnValidationError="True" 。 注: 如此一来, 则可以产生Validation.ErrorEvent事件
  • 3.通过自定义的 ValidationExceptionBehavior 继承于 Behavior, 用于监听 Validation.ErrorEvent 的错误事件。
  • 4.在 ValidationExceptionBehavior 中通过 AssociatedObjectde的DataContex获取到关联当前View的DataContex, 从而改变DataContext的后端验证条件。

1.设置属性自定义的验证类并添加 NotifyOnValidationError="True" 属性

                        <TextBox  Margin="15 0 10 0"
Style="{StaticResource MaterialDesignFloatingHintTextBox}" materialDesign:HintAssist.Hint="登录名 *">
<TextBox.Text>
<Binding Path="Model.Account" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
<Binding.ValidationRules>
<domain:CustomizeValidationRule validationType="Str"
minLength="3" maxLength="10"
errorMessage="输入长度范围 [3-10]字"
ValidatesOnTargetUpdated="True" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>

2.自定义 IValidationExceptionHandler 接口, ViewModel继承IValidationExceptionHandler , 用于接收前端的验证结果。

public interface IValidationExceptionHandler
{
/// <summary>
/// 是否有效
/// </summary>
bool IsValid
{
get;
set;
}
}

3. 自定义 ValidationExceptionBehavior, 用于监听处理View的错误事件

    /// <summary>
/// 验证行为类,可以获得附加到的对象
/// </summary>
public class ValidationExceptionBehavior : Behavior<FrameworkElement>
{
/// <summary>
/// 错误计数器
/// </summary>
private int _validationExceptionCount = 0; /// <summary>
/// 附加对象时
/// </summary>
protected override void OnAttached()
{
//附加对象时,给对象增加一个监听验证错误事件的能力,注意该事件是冒泡的
this.AssociatedObject.AddHandler(Validation.ErrorEvent, new EventHandler<ValidationErrorEventArgs>(this.OnValidationError));
} #region 获取实现接口的对象 /// <summary>
/// 获取对象
/// </summary>
/// <returns></returns>
private IValidationExceptionHandler GetValidationExceptionHandler()
{
if (this.AssociatedObject.DataContext is IValidationExceptionHandler)
{
var handler = this.AssociatedObject.DataContext as IValidationExceptionHandler; return handler;
} return null;
} #endregion #region 验证事件方法 /// <summary>
/// 验证事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnValidationError(object sender, ValidationErrorEventArgs e)
{
try
{
var handler = GetValidationExceptionHandler(); var element = e.OriginalSource as UIElement; if (handler == null || element == null)
return; if (e.Action == ValidationErrorEventAction.Added)
{
_validationExceptionCount++; }
else if (e.Action == ValidationErrorEventAction.Removed)
{
_validationExceptionCount--;
}
handler.IsValid = _validationExceptionCount == 0;
}
catch (Exception ex)
{
throw ex;
}
} #endregion
}

4. View容器最外层注册添加的监听错误事件 ValidationExceptionBehavior

   <i:Interaction.Behaviors>
<domain:ValidationExceptionBehavior></domain:ValidationExceptionBehavior>
</i:Interaction.Behaviors>

5. ViewModel 通过实现 IValidationExceptionHandler 来获取前端的验证结果

根据前端验证的结果, 正确保存, 错误进行提示

        public override void Save()
{
if (!this.IsValid)
{
MessageBox.Show("输入的格式有误,请重新输入!");
return;
}
base.Save();
}

效果:

WPF ValidationRules(MVVM 数据验证)的更多相关文章

  1. WPF中的数据验证

    数据验证 WPF的Binding使得数据能够在数据源和目标之间流通,在数据流通的中间,便能够对数据做一些处理. 数据转换和数据验证便是在数据从源到目标 or 从目标到源 的时候对数据的验证和转换. V ...

  2. 使用Data Annotations进行手动数据验证

    Data Annotations是在Asp.Net中用于表单验证的 它通过Attribute直接标记字段的有效性,简单且直观.在非Asp.Net程序中(如控制台程序),我们也可以使用Data Anno ...

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

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

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

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

  5. 【WPF】数据验证

    原文:[WPF]数据验证 引言      数据验证在任何用户界面程序中都是不可缺少的一部分.在WPF中,数据验证更是和绑定紧紧联系在一起,下面简单介绍MVVM模式下常用的几种验证方式. 错误信息显示 ...

  6. wpf数据验证实例及常用方法小结

    虽然标题是wpf数据验证,但并不是对IDataErrorInfo.ValidationRule.属性中throw Exception这几种验证方式的介绍: 之前做项目时(例如员工工资管理),根据员工编 ...

  7. 在WPF对话框中如何验证用户提供的数据

    在WPF中,MS在msdn的WPF应用程序开发中对用户输入的数据验证做了示范,基本思想就是添加各种类型的校验规则,比如最大最小值.字符串长度.是否为空等等,在后在界面绑定数据时添加数据字段的校验.这样 ...

  8. [WPF] 在 ViewModel 中让数据验证出错(Validation.HasError)的控件获得焦点

    1. 需求 在 MVVM 中 ViewModel 和 View 之间的交互通常都是靠 Icommand 和 INotifyPropertyChanged,不过有时候还会需要从 MVVM 中控制 Vie ...

  9. WPF数据验证方式

    WPF有两种数据验证的方式: 1 在数据对象上进行验证:普通属性验证或者实现IDataErrorInfo接口 2 可以再绑定规则上进行验证:ExceptionValidationRule异常验证规则 ...

随机推荐

  1. C# virtual 和 abstract 区别

    Virtual方法(虚方法) virtual 关键字用于在基类中修饰方法.virtual的使用会有两种情况: 情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法.那么在对派生类实例 ...

  2. iOS 应用程序启动时要做什么

    当您的应用程序启动(无论是在前台或后台),使用您的应用程序委托application:willFinishLaunchingWithOptions:和application:didFinishLaun ...

  3. mysql操作篇续

    # ### part1. 数据类型 - 时间date YYYY-MM-DD 年月日 (纪念日)time HH:MM:SS 时分秒 (体育竞赛)year YYYY 年份值 (酒的年份,82年拉菲)dat ...

  4. 将Docker容器转移至另一服务器

    1 把当前的容器提交为一个镜像: docker commit 容器名 镜像名 2 将镜像存为tar文件 docker save 镜像名 >备份文件.tar 3将 备份文件.tar 复制到目的主机 ...

  5. 渗透测试之wep无线网络破解

    WEP 无线网络破解 WEP(无线等效协议)于 1999 年诞生,并且是用于无线网络的最古老的安全标准.在 2003 年,WEP 被 WPA 以及之后被 WPA2 取代.由于可以使用更加安全的协议,W ...

  6. nginx 文件服务器配置,模板配置文件,有注释

    # For more information on configuration, see: # * Official English Documentation: http://nginx.org/e ...

  7. Ubuntu 18.04安装 pyenv、pyenv-virtualenv、virtualenv、Numpy、SciPy、Pillow、Matplotlib

    1.目前Python版本管理工具有很多,pyenv是比较好用的一款,安装如下: 输入: git clone https://github.com/pyenv/pyenv.git ~/.pyenv ec ...

  8. C++编程思想 - 对象的创建和使用

    前言 用户定义的数据类型(data type)或类(class),是C++区别于传统过程型语言的地方. 通常将创建好的类库存放在库(library)中. 本篇会使用几个C++类库(class libr ...

  9. Node.js中的模块接口module.exports

    在写node.js代码时,我们经常需要自己写模块(module).同时还需要在模块最后写好模块接口,声明这个模块对外暴露什么内容.实际上,node.js的模块接口有多种不同写法.在此做了个简单的总结. ...

  10. Redis与python

    一.Redis介绍 Redis是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库(非关系型数据库). 本质:将数据保存在内存中. 用途:缓存.消息队列. 1.Redis的特点 R ...