WPF中使用IDataErrorInfo进行规则验证

  • A+
所属分类:.NET技术
摘要

使用 IDataErrorInfo 进行数据对象验证主要有以下步骤:完整的 View 代码如下:


WPF中使用IDataErrorInfo进行数据对象验证

使用 IDataErrorInfo 进行数据对象验证主要有以下步骤:

1、定义一个集合,用于收集错误信息:

private Dictionary<string, string> dataErrors = new Dictionary<string, string>(); 

2、需要验证的对象的类需要实现 IDataErrorInfo 接口:

  • 具体的数据验证在 this[string columnName] 的 get 访问器中进行。为了防止在处理验证信息时进行大量的条件判断,在这里使用了命名空间 System.ComponentModel.DataAnnotations,将验证条件分离,以 Attribute 的形式关联到每个字段上。
  • 错误信息在这里存储在集合 dataErrors 中,所以需要补充两个方法,用于操作错误dataErrors 。
  • 实现以上处理的 ViewModel 代码如下:
using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Command; using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Windows;  namespace IDataErrorInfoDemo.ViewModel {     [MetadataType(typeof(MainViewModel))]     public class MainViewModel : ViewModelBase, IDataErrorInfo     {         public MainViewModel()         {             SaveCommand = new RelayCommand(() =>             {                 if (dataErrors.Count == 0) MessageBox.Show("验证通过!");                 else                 {                     StringBuilder sb = new StringBuilder();                     sb.Append("验证失败:rn");                     foreach (var error in dataErrors)                     {                         sb.Append(error + "rn");                     }                     MessageBox.Show(sb.ToString());                 }             });         }          /// <summary>         /// 页面提交命令         /// </summary>         public RelayCommand SaveCommand { get; set; }          private string userName;         /// <summary>         /// 用户名         /// </summary>         [Required]         public string UserName         {             get { return userName; }             set { userName = value; RaisePropertyChanged(); }         }          private String userEmail;         /// <summary>         /// 用户邮件         /// </summary>         [Required]         [StringLength(100, MinimumLength = 2)]         [RegularExpression("^\s*([A-Za-z0-9_-]+(\.\w+)*@(\w+\.)+\w{2,5})\s*$", ErrorMessage = "邮箱地址填写错误。")]         public String UserEmail         {             get { return userEmail; }             set { userEmail = value; }         }          /// <summary>         /// 错误集合         /// </summary>         private Dictionary<string, string> dataErrors = new Dictionary<string, string>();          //IDataErrorInfo的固定实现         public string Error         {             get;         }          public string this[string columnName]         {             get             {                 ValidationContext vc = new ValidationContext(this, null, null);                 vc.MemberName = columnName;                 var res = new List<ValidationResult>();                 var result = Validator.TryValidateProperty(this.GetType().GetProperty(columnName).GetValue(this, null), vc, res);                 if (res.Count > 0)                 {                     string error = string.Join(Environment.NewLine, res.Select(r => r.ErrorMessage).ToArray());                     AddDic(dataErrors, vc.MemberName, error);                     return error;                 }                 RemoveDic(dataErrors, vc.MemberName);                 return null;             }         }          /// <summary>         /// 移除错误信息         /// </summary>         /// <param name="dics"></param>         /// <param name="dicKey"></param>         private void RemoveDic(Dictionary<string, string> dics, string dicKey)         {             dics.Remove(dicKey);         }          /// <summary>         /// 添加错误信息         /// </summary>         /// <param name="dics"></param>         /// <param name="dicKey"></param>         private void AddDic(Dictionary<string, string> dics, string dicKey,string dicValue)         {             if (!dics.ContainsKey(dicKey)) dics.Add(dicKey, dicValue);         }     } } 

3、在 View 中对需要验证的元素的 Binding 开启属性 :ValidatesOnDataErrors=True

<TextBox          Text="{Binding UserEmail, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"          Width="200"          Height="30" /> 

完整的 View 代码如下:

<Window     x:Class="IDataErrorInfoDemo.MainWindow"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"     xmlns:local="clr-namespace:IDataErrorInfoDemo"     Title="MainWindow"     Width="800"     Height="450"     mc:Ignorable="d">     <Grid>         <Grid.RowDefinitions>             <RowDefinition />             <RowDefinition />             <RowDefinition />         </Grid.RowDefinitions>         <StackPanel             HorizontalAlignment="Center"             VerticalAlignment="Center"             Orientation="Horizontal">             <Label                 Content="用户名:"                 Margin="0,0,10,0"                 FontSize="20" />             <TextBox                 Text="{Binding UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"                 Width="200"                 Height="30" />         </StackPanel>         <StackPanel Grid.Row="1"             HorizontalAlignment="Center"             VerticalAlignment="Center"             Orientation="Horizontal">             <Label                 Content="邮箱:"                 Margin="0,0,10,0"                 FontSize="20" />             <TextBox                 Text="{Binding UserEmail, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"                 Width="200"                 Height="30" />         </StackPanel>         <Button Grid.Row="2"             Content="提交"             Command="{Binding SaveCommand}"             Width="200"             Height="30"             Margin="0,20,0,0" />     </Grid> </Window> 

4、实现效果如下:

WPF中使用IDataErrorInfo进行规则验证