首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 媒体动画 > CAD教程 >

[Silverlight入门系列]施用MVVM模式(5):异步Validation数据验证和INotifyDataErrorInfo接口

2012-12-27 
[Silverlight入门系列]使用MVVM模式(5):异步Validation数据验证和INotifyDataErrorInfo接口数据验证(Valid

[Silverlight入门系列]使用MVVM模式(5):异步Validation数据验证和INotifyDataErrorInfo接口

数据验证(Validation)是界面程序的常见需求,例如使用正则表达式验证用户输入的Email地址是否合法,然后在界面给出错误提示信息。在Sivlerlight的MVVM模式中,我们在Model和ViewModel可以做Validation,然后需要把Model和ViewModel的Validation结果和错误信息通知视图(View)。在WPF中,我们使用IDataErrorInfo,在Silverlight4中,建议使用INotifyDataErrorInfo。

IDataErrorInfo

先简单说一下IDataErrorInfo,这个接口实现了简单的数据验证和错误报告功能,只能说聊胜于无吧。例子:

?

代码说明 ViewModel基类:

?

  1 using System;  2 using System.Net;  3 using System.Windows;  4 using System.Linq;  5 using System.Windows.Controls;  6 using System.Windows.Documents;  7 using System.Windows.Ink;  8 using System.Windows.Input;  9 using System.Windows.Media; 10 using System.Windows.Media.Animation; 11 using System.Windows.Shapes; 12 using System.ComponentModel; 13 using System.Collections.Generic; 14 using System.Collections; 15  16 namespace AsycValidation 17 { 18     public class BasicViewModel : INotifyPropertyChanged, INotifyDataErrorInfo 19     { 20         public event PropertyChangedEventHandler PropertyChanged; 21         public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; 22  23  24         private Dictionary<string, List<ValidationErrorInfo>> _errors = 25                       new Dictionary<string, List<ValidationErrorInfo>>(); 26  27  28         protected void RemoveErrorFromPropertyAndNotifyErrorChanges( 29                                  string propertyName, 30                                  int errorCode) 31         { 32             if (_errors.ContainsKey(propertyName)) 33             { 34                 RemoveErrorFromPropertyIfErrorCodeAlreadyExist(propertyName, errorCode); 35  36                 NotifyErrorsChanged(propertyName); 37             } 38         } 39  40         private void RemoveErrorFromPropertyIfErrorCodeAlreadyExist( 41                                  string propertyName, 42                                  int errorCode) 43         { 44             if (_errors.ContainsKey(propertyName)) 45             { 46                 var errorToRemove = _errors[propertyName].SingleOrDefault( 47                                        error => error.ErrorCode == errorCode); 48  49                 if (errorToRemove != null) 50                 { 51                     _errors[propertyName].Remove(errorToRemove); 52  53  54  55  56                     if (_errors[propertyName].Count == 0) 57                         _errors.Remove(propertyName); 58                 } 59             } 60         } 61         protected void AddErrorToPropertyAndNotifyErrorChanges( 62                                   string propertyName, 63                                   ValidationErrorInfo errorInfo) 64         { 65             RemoveErrorFromPropertyIfErrorCodeAlreadyExist(propertyName, errorInfo.ErrorCode); 66             if (!_errors.ContainsKey(propertyName)) 67                 _errors.Add(propertyName, new List<ValidationErrorInfo>()); 68  69             _errors[propertyName].Add(errorInfo); 70  71             NotifyErrorsChanged(propertyName); 72         } 73  74  75         public IEnumerable GetErrors(string propertyName) 76         { 77             if (!_errors.ContainsKey(propertyName)) 78                 return _errors.Values; 79  80             return _errors[propertyName]; 81         } 82  83  84         public bool HasErrors 85         { 86             get { return this._errors.Count > 0; } 87         } 88  89  90         private void NotifyErrorsChanged(string propertyName) 91         { 92             if (ErrorsChanged != null) 93                 ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName)); 94         } 95  96  97         protected void NotifyPropertyChanged(string propertyName) 98         { 99             if (PropertyChanged != null)100                 PropertyChanged(this, new PropertyChangedEventArgs(propertyName));101         }102 103     }104 }

?

Model:

?

 1 using System; 2 using System.Net; 3 using System.Windows; 4 using System.Windows.Controls; 5 using System.Windows.Documents; 6 using System.Windows.Ink; 7 using System.Windows.Input; 8 using System.Windows.Media; 9 using System.Windows.Media.Animation;10 using System.Windows.Shapes;11 using System.ComponentModel;12 13 namespace AsycValidation14 {15     public class CompanyModel : INotifyPropertyChanged16     {17         public event PropertyChangedEventHandler PropertyChanged;18 19         public int CompanyID { get; set; }20 21         private string _CompanyName;22         public string CompanyName23         {24             get { return _CompanyName; }25             set26             {27                 _CompanyName = value;28 29                 if (PropertyChanged != null)30                 {31                     PropertyChanged(this, new PropertyChangedEventArgs("CompanyName"));32                 }33             }34         }35     }36 }

?

ViewModel,继承了BaseViewModel基类:

?

 1 using System; 2 using System.Net; 3 using System.Windows; 4 using System.Windows.Controls; 5 using System.Windows.Documents; 6 using System.Windows.Ink; 7 using System.Windows.Input; 8 using System.Windows.Media; 9 using System.Windows.Media.Animation;10 using System.Windows.Shapes;11 using AsycValidation.Web;12 13 namespace AsycValidation14 {15     public class CompanyViewModel : BasicViewModel16     {17         public CompanyModel CompanyModelData { get; set; }18 19         public CompanyViewModel(CompanyModel model)20         {21             CompanyModelData = model;22         }23 24         private string _CompanyName = null;25         private const int ACCOUNT_ALREADY_EXIST_ERROCODE = 100;26 27         DomainService1 service = new DomainService1();28 29         public string CompanyName30         {31             get32             {33                 return _CompanyName;34             }35             set36             {37                 if (_CompanyName != value)38                 {39                     var propertyName = "CompanyName";40 41                     ValidateAccountAlreadyExists(42                                     value,43                                     propertyName,44                                     ACCOUNT_ALREADY_EXIST_ERROCODE,45                                     string.Format("Company with the ID {0} already exists", value));46 47                     _CompanyName = value;48                     NotifyPropertyChanged(propertyName);49                 }50             }51         }52 53         private void ValidateAccountAlreadyExists(54                                         string CompanyID,55                                         string propertyName,56                                         int errorCode,57                                         string errorMsg)58         {59             service.DoesCompanyExists(60                  CompanyID,61                  invokeOperation =>62                  {63                      if (invokeOperation.Value)64                      {65                          AddErrorToPropertyAndNotifyErrorChanges(66                              propertyName,67                              new ValidationErrorInfo()68                              {69                                  ErrorCode = errorCode,70                                  ErrorMessage = errorMsg71                              });72                      }73                      else74                      {75                          RemoveErrorFromPropertyAndNotifyErrorChanges(76                                propertyName,77                                errorCode);78                      }79                  },80                  null);81         }82 83     }84 }

?

View / XAML

?

 1 <UserControl x:Class="AsycValidation.MainPage" 2     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6     xmlns:wm="clr-namespace:AsycValidation" 7     mc:Ignorablecolor: #0000f 

热点排行