对于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. 缓存cache(擦车)

    第一次接触到Cache的时候,是在WebForm中,第一次接触,我就再也没能忘记,cache(擦车,的拼音) 客户端浏览器缓存https://blog.csdn.net/y874961524/arti ...

  2. Javase之集合体系(4)之Map集合

    集合体系之Map集合 ##Map<K,V>( 接口 ) 特点:将键映射到值对象,一个映射不能包含重复的键:每个键只能映射一个值 Map集合与Collection集合的区别 ​ Map集合存 ...

  3. Sublime设置格式化代码快捷键ctrl+shift+r

    1.以管理员身份运行sublime 2.首选项---按键绑定-用户,将以下代码复制即可(这里注意不要忘记在最后一行添加逗号哦) { "keys": ["ctrl+shif ...

  4. ORA-1562 and ORA-1650 Unable to Extend Rollback Segment (Doc ID 1066542.6)

    ORA-1562 and ORA-1650 Unable to Extend Rollback Segment (Doc ID 1066542.6) APPLIES TO: Oracle Databa ...

  5. PHP 循环引用的问题

    问题 为了引出问题, 先来看下面一段代码: <?php $arr = [ 'a', 'b', 'c', 'd', ]; foreach ($arr as &$each){ echo $e ...

  6. springboot中的照片上传工具类

    public class UploadImgUtils { private static String savePath = ""; /** * 上传照片工具类 * * @para ...

  7. Educational Codeforces Round 78 (Rated for Div. 2) --补题

    链接 直接用数组记录每个字母的个数即可 #include<bits/stdc++.h> using namespace std; int a[26] = {0}; int b[26] = ...

  8. MongoDB图形化工具(三)

    一.安装 下载地址:https://www.mongodbmanager.com/download 注意:在下载的时候需要对应上自己安装的mongodb版本. 双击安装 选择“Full install ...

  9. Leetcode53_Spiral_Matrix

    Spiral_Matrix https://leetcode-cn.com/problems/spiral-matrix/ //当行数只有一行: 1. n = 1; m -> 0; //当列数只 ...

  10. 在实际工作中使用requests+unittest进行接口测试

    之前学习python做接口测试时,用的时requests+excel的方式来进行接口测试,后来在工作中也用unittest来做了一个项目的接口测试,接口测试用例完全基于unittest来编写,把大致步 ...