WPF中使用ValidationRule自定义验证规则
本文主要是展示在 WPF 中使用 ValidationRule 自定义验证规则,同时展示两种错误响应方式。一种是通过 Behavior 传递到 ViewModel 中,然后进行错误信息响应;一种是直接在 View 中遍历当前也的所有错误元素,在页面中通过事件统一响应。
1、自定义验证规则类
这里自定义两个验证规则类,分别用于验证 "用户名"输入不可为空、"邮箱"输入值需满足格式要求。
两个类需要继承 ValidationRule 类。ValidationRule 是抽象类,需要具体实现 Validate 方法。代码如下:
NotEmptyValidationRule.cs
using System.Globalization;using System.Windows.Controls;namespace MyValidationRuleDemo.MyValidationRules{ public class NotEmptyValidationRule : ValidationRule { public override ValidationResult Validate(object value, CultureInfo cultureInfo) { return string.IsNullOrWhiteSpace((value ?? "").ToString()) ? new ValidationResult(false, "不能为空") : new ValidationResult(true, null); } }}
EmailValidationRule.cs
using System.Globalization;using System.Text.RegularExpressions;using System.Windows.Controls;namespace MyValidationRuleDemo.MyValidationRules{ public class EmailValidationRule : ValidationRule { public override ValidationResult Validate(object value, CultureInfo cultureInfo) { Regex emailRegex = new Regex("^\\s*([A-Za-z0-9_-]+(\\.\\w+)*@(\\w+\\.)+\\w{2,5})\\s*$"); string str = (value ?? "").ToString(); if (!string.IsNullOrWhiteSpace(str)) { if (!emailRegex.IsMatch(str)) { return new ValidationResult(false, "邮箱地址错误!"); } } return new ValidationResult(true, null); } }}
2、在前端页面中添加验证
在前端页面中需要进行以下操作:
添加自定义的 ValidationRule 所有的命名空间;
在需要验证的控件上的 Binding 上对应的自定义验证规则类;
<Binding.ValidationRules> <valRules:EmailValidationRule /></Binding.ValidationRules>
具体代码如下:
<Window x:
前端页面绑定的验证参数具体如下:
using GalaSoft.MvvmLight;using GalaSoft.MvvmLight.Command;namespace MyValidationRuleDemo.ViewModel{ public class MainViewModel : ViewModelBase { public MainViewModel() { } private string userName; /// <summary> /// 用户名 /// </summary> public string UserName { get { return userName; } set { userName = value; RaisePropertyChanged(); } } private string userEmail; /// <summary> /// 用户邮件 /// </summary> public string UserEmail { get { return userEmail; } set { userEmail = value; RaisePropertyChanged(); } } }}
此时,自定义的验证规则已经生效。当页面输入不符合规则时,会默认的红框进行标记。这是 WPF 中默认的效果。效果如下图:
3、使用 Behavior 自定义响应效果
上面虽然已经在页面上有了基本的错误响应效果,但是效果过于单一。这里我们在这里使用 Behavior 监听 Validation.Error 事件,并将错误信息传递到 ViewModel 中进行统一进行错误提醒。同时,在 MVMM 架构中将错误信息传递到 ViewModel 中进行统一处理,在有需要的时候也有利于业务逻辑处理。
3.1、实现步骤
进行以上操作需要进行以下步骤:
开启验证错误的通知属性 NotifyOnValidationError="True" 。这样就可以产生 Validation.Error 事件。
<TextBox Width="200" Height="30"> <TextBox.Text> <Binding Path="UserEmail" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <valRules:EmailValidationRule /> </Binding.ValidationRules> </Binding> </TextBox.Text></TextBox>
通过自定义的 ValidationExceptionBehavior 继承于 Behavior,用于监听 Validation.Error 的错误事件。
protected override void OnAttached(){ //添加 Validation.Error 事件监听 this.AssociatedObject.AddHandler(Validation.ErrorEvent, new EventHandler<ValidationErrorEventArgs>(OnValidationError));}
View 中添加 Behavior;
<i:Interaction.Behaviors> <local:ValidationExceptionBehavior /></i:Interaction.Behaviors>
在 ValidationExceptionBehavior 中通过 AssociatedObject 的DataContext 获取到关联当前View的ViewModel。并将错误提示统一收集到 ViewModel 的 ErrorList 。
private void OnValidationError(Object sender, ValidationErrorEventArgs e){ MainViewModel mainModel = null; if (AssociatedObject.DataContext is MainViewModel) { mainModel = this.AssociatedObject.DataContext as MainViewModel; } if (mainModel == null) return; //OriginalSource 触发事件的元素 var element = e.OriginalSource as UIElement; if (element == null) return; //ValidationErrorEventAction.Added 表示新产生的行为 if (e.Action == ValidationErrorEventAction.Added) { mainModel.ErrorList.Add(e.Error.ErrorContent.ToString()); } else if (e.Action == ValidationErrorEventAction.Removed) //ValidationErrorEventAction.Removed 该行为被移除,即代表验证通过 { mainModel.ErrorList.Remove(e.Error.ErrorContent.ToString()); }}
在 View 中按钮绑定的 Command 中统一处理 ErrorList;
public RelayCommand SaveCommand { get; set; }public MainViewModel(){ SaveCommand = new RelayCommand(() => { StringBuilder sb = new StringBuilder(); foreach (var error in ErrorList) { sb.Append(error + "\r\n"); } MessageBox.Show(sb.ToString()); });}
开启 ValidationRule 的属性 ValidatesOnTargetUpdated="True",否则在加载页面后,文本框中未输入值则不会进行验证。
<Binding.ValidationRules> <valRules:EmailValidationRule ValidatesOnTargetUpdated="True" /></Binding.ValidationRules>
3.2、具体代码
完整代码如下:
ValidationExceptionBehavior.cs
using MyValidationRuleDemo.ViewModel;using System;using System.Windows;using System.Windows.Controls;using System.Windows.Interactivity;namespace MyValidationRuleDemo{ public class ValidationExceptionBehavior : Behavior<FrameworkElement> { protected override void OnAttached() { //添加 Validation.Error 事件监听 this.AssociatedObject.AddHandler(Validation.ErrorEvent, new EventHandler<ValidationErrorEventArgs>(OnValidationError)); } private void OnValidationError(Object sender, ValidationErrorEventArgs e) { MainViewModel mainModel = null; if (AssociatedObject.DataContext is MainViewModel) { mainModel = this.AssociatedObject.DataContext as MainViewModel; } if (mainModel == null) return; //OriginalSource 触发事件的元素 var element = e.OriginalSource as UIElement; if (element == null) return; //ValidationErrorEventAction.Added 表示新产生的行为 if (e.Action == ValidationErrorEventAction.Added) { mainModel.ErrorList.Add(e.Error.ErrorContent.ToString()); } else if (e.Action == ValidationErrorEventAction.Removed) //ValidationErrorEventAction.Removed 该行为被移除,即代表验证通过 { mainModel.ErrorList.Remove(e.Error.ErrorContent.ToString()); } } protected override void OnDetaching() { //移除 Validation.Error 事件监听 this.AssociatedObject.RemoveHandler(Validation.ErrorEvent, new EventHandler<ValidationErrorEventArgs>(OnValidationError)); } }}
MainView.xaml
<Window x:
MainViewModel.cs
using GalaSoft.MvvmLight;using GalaSoft.MvvmLight.Command;using System.Collections.ObjectModel;using System.Text;using System.Windows;namespace MyValidationRuleDemo.ViewModel{ public class MainViewModel : ViewModelBase { public MainViewModel() { SaveCommand = new RelayCommand(() => { StringBuilder sb = new StringBuilder(); foreach (var error in ErrorList) { sb.Append(error + "\r\n"); } MessageBox.Show(sb.ToString()); }); } public RelayCommand SaveCommand { get; set; } private string userName; /// <summary> /// 用户名 /// </summary> public string UserName { get { return userName; } set { userName = value; RaisePropertyChanged(); } } private string userEmail; /// <summary> /// 用户邮件 /// </summary> public string UserEmail { get { return userEmail; } set { userEmail = value; RaisePropertyChanged(); } } private ObservableCollection<string> errorList = new ObservableCollection<string>(); /// <summary> /// 错误提示 /// </summary> public ObservableCollection<string> ErrorList { get { return errorList; } set { errorList = value; RaisePropertyChanged(); } } }}
3.3、效果展示
4、直接在页面中进行错误响应
错误响应也可以直接在 View 中通过事件直接处理。但是这样处理就比较麻烦,在获取错误列表时,我们可能需要编写代码,从而在 View 中所有控件中查询有错误的控件。
4.1、单个错误响应
Error 事件是使用冒泡策略的路出事件,我们在 Binding 了 ValidationRule 的控件的父容器上关联处理程序,即可为多个控件处理 Error 事件。
在 View.xaml 中添加如下代码:
<Grid Validation.Error="Grid_Error"> <!--这里面是具体的页面内容--></Grid>
关联的事件处理程序如下:
private void Grid_Error(object sender, ValidationErrorEventArgs e){ if (e.Action == ValidationErrorEventAction.Added) { MessageBox.Show(e.Error.ErrorContent.ToString()); }}
4.2、获取错误列表
循环遍历整个 View 中的元素,并将存在的错误信息收集到一个字符串中,然后点击按钮时将该字符串中的信息展示出来。程序代码如下:
private void Button_Click(object sender, RoutedEventArgs e){ string message; if (HasErrors(out message)) { MessageBox.Show(message); }}private bool HasErrors(out string message){ StringBuilder sb = new StringBuilder(); GetError(sb, this.grid); message = sb.ToString(); return !string.IsNullOrWhiteSpace(message);}private void GetError(StringBuilder sb, DependencyObject obj){ foreach (object child in LogicalTreeHelper.GetChildren(obj)) { StackPanel element = child as StackPanel; if (element == null) continue; foreach (var ele in element.Children) { TextBox textBox = ele as TextBox; if (textBox == null) continue; if (Validation.GetHasError(textBox)) { foreach (ValidationError error in Validation.GetErrors(textBox)) { sb.Append(error.ErrorContent.ToString() + "\r\n"); } GetError(sb, element); } } }}
原文转载:http://www.shaoqun.com/a/527601.html
etoro:https://www.ikjzd.com/w/1402
声网agora:https://www.ikjzd.com/w/2176
WPF中使用ValidationRule自定义验证规则本文主要是展示在WPF中使用ValidationRule自定义验证规则,同时展示两种错误响应方式。一种是通过Behavior传递到ViewModel中,然后进行错误信息响应;一种是直接在View中遍历当前也的所有错误元素,在页面中通过事件统一响应。1、自定义验证规则类这里自定义两个验证规则类,分别用于验证"用户名"输入不可为空、"邮箱"输入值需
e邮包:e邮包
墩煌网:墩煌网
eGenesis:eGenesis
DTDEX:DTDEX
"黑五"、"网一"狂欢将至,卖家怎么定价不亏本?怎么打折最赚钱?:"黑五"、"网一"狂欢将至,卖家怎么定价不亏本?怎么打折最赚钱?
没有评论:
发表评论