自定义扩展Validation类,验证框架的总结和建议

最后更新于:2022-04-01 14:21:08

![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-18_56eb67c868925.jpg) [Silverlight Validation验证实例教程系列](http://www.silverlightchina.net/html/zhuantixilie/getstart/2010/0924/2035.html)已经写了[七篇](http://www.cnblogs.com/jv9/)了,今天将完成计划中的最后一个话题,创建自定义扩展验证类,本篇是根据一些读者反馈的问题总结而来的,在本篇最后,将简单的对目前Silverlight Validation验证框架提供的验证机制进行总结性的对比和归纳,希望能够帮助大家在实际项目中定位和应用验证框架。 阅读过[前几篇Silverlight实例教程](http://www.silverlightchina.net/html/zhuantixilie/getstart/2010/0924/2035.html)的朋友,给我留言和来信,大家对于Silverlight Validation类的使用,总感觉有些不灵活,特别是在自定义使用时,很难轻松的控制错误验证的捕获和弹出。 下面,我将演示另外一个实例,该实例将帮助开发人员创建自定义扩展Validation类,该类允许开发人员,方便的控制验证错误弹出,验证错误清除,以及验证校验方法。 **Silverlight Validation自定义扩展类** 本实例仍旧使用SilverlightValidationDemo项目,在Mainpage中创建一个简单的UI,进行演示: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-18_56eb67cedf779.jpg) [](http://images.cnblogs.com/cnblogs_com/jv9/WindowsLiveWriter/SilverlightValidation_D5A9/image_2.png) ~~~ <StackPanel Margin="5">                   <StackPanel Orientation="Horizontal" Margin="5">                  <TextBlock Text="产品名: " VerticalAlignment="Center"/>                  <TextBox x:Name="txtProduct" Width="200" />              </StackPanel>              <StackPanel Orientation="Horizontal" Margin="5">                  <TextBlock Text="数  量: " VerticalAlignment="Center"/>                  <TextBox x:Name="txtAmount" Width="200"  />              </StackPanel>              <StackPanel Orientation="Horizontal" Margin="5">                  <TextBlock Text="单  价: " VerticalAlignment="Center"/>                  <TextBox x:Name="txtPrice" Width="200" />              </StackPanel>              <StackPanel Orientation="Horizontal" >                  <Button x:Name="btBuy" Content="购  买" Margin="5" />                  <Button x:Name="btReset" Content="重  置" Margin="5" />              </StackPanel>  </StackPanel> ~~~ 根据上图,我们看到,我们将对产品名,产品数量和产品单价进行验证,在Xaml代码中,没有对Text进行绑定,这些,我们将在代码中进行实现。 在完成上面UI的创建,我们需要创建一个静态类ValidationExtension,在该类中,我们将创建自定义验证方法,以及验证错误信息控制方法。 在ValidationExtension类中,我们将使用以下三个静态方法,接管Silverlight Validation默认的验证捕获,其代码分别是: ~~~ public static void SetValidation(this FrameworkElement frameworkElement, string message)  {              CustomizeValidation customValidation = new CustomizeValidation(message);              Binding binding = new Binding("ValidationError")              {                  Mode = System.Windows.Data.BindingMode.TwoWay,                  NotifyOnValidationError = true,                  ValidatesOnExceptions = true,                  Source = customValidation              };              frameworkElement.SetBinding(Control.TagProperty, binding);  } ~~~ SetValidation静态方法,将设置FrameworkElement元素绑定ValidationError验证错误信息,其中设置NotifyOnValidationError 和ValidatesOnExceptions 为True,允许控件对异常和验证错误进行捕获和反馈。 ~~~ public static void RaiseValidationError(this FrameworkElement frameworkElement)          {              BindingExpression b = frameworkElement.GetBindingExpression(Control.TagProperty);              if (b != null)              {                  ((CustomizeValidation)b.DataItem).ShowErrorMessage = true;                  b.UpdateSource();              }          } ~~~ RaiseValidationError静态方法,在验证错误绑定后,通过该方法将错误异常显示在客户端,通过UpdateSource方法更新客户端错误异常显示。简单的理解就是在客户端控件对象,弹出异常错误提示信息。 ~~~ public static void ClearValidationError(this FrameworkElement frameworkElement)          {              BindingExpression b = frameworkElement.GetBindingExpression(Control.TagProperty);              if (b != null)              {                  ((CustomizeValidation)b.DataItem).ShowErrorMessage = false;                  b.UpdateSource();              }          } ~~~ ClearValidationError静态方法,和RaiseValidationError静态方法正好相反,调用该方法将清空当前对象上显示的异常错误信息。 以上三个方法的调用,将在后文演示。下面需要添加简单的验证条件,帮助客户端捕获验证错误信息,为了方便起见,这里,创建了对数字的判断和对双精度型的数据判断,代码如下: ~~~ public static bool IsNumberValid(this string inputNumber)          {              bool isNumberValid = true;              int number = -1;              if (!Int32.TryParse(inputNumber, out number))              {                  isNumberValid = false;              }              return isNumberValid;          }  ~~~ IsNumberValid静态方法,判断当前对象中输入字符是否为数字; ~~~ public static bool IsPriceValid(this string inputPrice)          {              bool isPriceValid = true;              double minprice = 8.8;              if (Convert.ToDouble(inputPrice) < minprice)              {                  isPriceValid = false;              }              return isPriceValid;          }  ~~~ IsPriceValid静态方法,判断当前对象中输入字符是否大于最小价格,如果False,则返回验证错误。 这里大家已经留意到,ValidationExtension自定义扩展类没有继承和实现任何验证类或接口,独立存在。 在以上静态方法中,我们用到了CustomizeValidation自定义验证类中的属性成员,在过去的几篇中,我们仅在CustomizeValidation中定义了一个简单的自定义验证方法,而现在我们需要添加两个简单的属性和一个新的构造函数,其代码如下: ~~~ #region Private memebers          private string message;          #endregion          #region Public Property          public bool ShowErrorMessage          {              get;              set;          }          public object ValidationError          {              get              {                  return null;              }              set              {                  if (ShowErrorMessage)                  {                      throw new ValidationException(message);                  }              }          }  #endregion ~~~ 构造函数: ~~~ public CustomizeValidation(string message)          {              this.message = message;          } ~~~ 其目的是为了收集验证错误信息。 完成了以上自定义代码后,我们可以在客户端进行简单的调用代码设置: 目前,我们希望,点击“购买”按钮后,对用户输入信息进行验证判断,如果有错误异常,则弹出验证错误信息, 这里我们仅需要添加部分代码到btBuy.Click事件即可。 ~~~ #region Validation Extension          private void btBuy_Click(object sender, RoutedEventArgs e)          {              bool isValid = true;              txtProduct.ClearValidationError();              txtAmount.ClearValidationError();              txtPrice.ClearValidationError();              if (txtProduct.Text == "")              {                  txtProduct.SetValidation("请输入产品名称");                  txtProduct.RaiseValidationError();                  isValid = false;              }              if (txtAmount.Text == "" || !txtAmount.Text.IsNumberValid())              {                  txtAmount.SetValidation("请输入一个整数");                  txtAmount.RaiseValidationError();                  isValid = false;              }              if (txtPrice.Text == "" || !txtPrice.Text.IsPriceValid())              {                  txtPrice.SetValidation("最小出价8.8");                  txtPrice.RaiseValidationError();                  isValid = false;              }              if (isValid)              {                  HtmlPage.Window.Alert("产品购买成功");                  ResetForm();              }          }          private void btReset_Click(object sender, RoutedEventArgs e)          {              ResetForm();          }          private void ResetForm()          {              txtProduct.ClearValidationError();              txtAmount.ClearValidationError();              txtPrice.ClearValidationError();              txtProduct.Text = "";              txtAmount.Text = "";              txtPrice.Text = "";          }  #endregion ~~~ 通过SetValidation,设置验证错误提示信息,通过RaiseValidationError弹出验证错误信息,每次点击前,调用ClearValidationError清空当前验证错误。最终执行结果如下: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-18_56eb67cef0edd.jpg) [](http://images.cnblogs.com/cnblogs_com/jv9/WindowsLiveWriter/SilverlightValidation_D5A9/image_4.png) 到这里,我们已经完成了一个自定义扩展Validation类,大家可以根据这个思路扩展更多的验证校验方法,并应用到项目控件中。 **Silverlight Validation验证机制对比总结和建议** 在过去的几篇中,我们曾经详细介绍了四种Silverlight Validation验证机制,分别是 基本异常验证机制; DataAnnotation验证机制; IDataErrorInfo客户端同步验证机制; INotifyDataErrorInfo服务器端异步验证机制; 一些朋友发邮件问我,这些验证机制在项目中的优势是什么?在实际项目中,如何选择适当的验证机制?下面有个简单的列表,将以上四种验证机制进行简单的归纳总结: <table border="1" cellspacing="0" cellpadding="0"><tbody><tr><td width="130"><p align="center"><strong>验证机制</strong></p></td><td width="237"><p align="center"><strong>优势</strong></p></td><td width="183"><p align="center"><strong>劣势</strong></p></td></tr><tr><td width="130"><p>基本异常验证机制</p></td><td width="237"><p>1. 适用任何数据类型验证;</p><p>2. 使用方法简单,仅需在Xaml代码中设置即可;</p></td><td width="183"><p>1. 只能在属性Setter中使用;</p><p>2. 不支持自定义方法验证</p><p>3. 每个成员每次仅能捕获一个验证错误</p></td></tr><tr><td width="130"><p>DataAnnotation验证机制</p></td><td width="237"><p>1. 不会引发异常错误;</p><p>2. 每个成员可以使用多个验证条件;</p><p>3. 使用方法简单,仅需声明属性即可;无需过多编写代码;</p><p>4. 支持自定义方法验证;</p></td><td width="183"><p>仅适合用于Datagrid和Dataform和一些可使用DataAnnotation属性的第三方控件</p></td></tr><tr><td width="130"><p>IDataErrorInfo客户端同步验证机制</p></td><td width="237"><p>1. 不会引发异常错误;</p><p>2. 支持自定义方法验证;</p></td><td width="183"><p>1. 不能捕获数据类型验证错误;</p><p>2. 每个数据成员每次仅能捕获一个验证错误;</p><p>3. 使用方法较为复杂;</p></td></tr><tr><td width="130"><p>INotifyDataErrorInfo服务器端异步验证机制</p></td><td width="237"><p>1. 不会引发异常错误;</p><p>2. 支持自定义方法验证;</p><p>3. 支持服务器端异步验证;</p><p>4. 每个成员可以使用多个验证条件;</p></td><td width="183"><p>1. 不能捕获数据类型验证错误;</p><p>2. 多条件验证下,仅支持显示第一个验证错误;</p><p>3. 使用方法复杂;</p></td></tr></tbody></table>   在使用Silverlight Validation框架是需要注意以下几点:   1. 使项目支持异常捕获,这样验证框架可支持数据类型校验; 2. 如果使用Datagrid和Dataform控件,推荐使用DataAnnotation验证机制; 3. 如果需要在客户端验证所有信息,推荐使用IDataErrorInfo验证机制; 4. 如果需要使用服务器端的验证方法,推荐使用INotifyDataErrorInfo验证机制。   相信大家在明白了以上各个验证机制的优势和劣势后,已经可以轻松掌握Silverlight Validation验证框架的应用了。 [Silverlight Validation实例教程系列](http://www.silverlightchina.net/html/zhuantixilie/getstart/2010/0924/2035.html),到这里即将完结,如果大家在阅读中,或者项目中遇到问题或者有不同的意见, 欢迎留言给我,我们一起讨论学习。 最后感谢每一位支持的朋友。 [源代码下载](http://www.silverlightchina.net/resource/code/2010/SilverlightValidationDemo.rar) 欢迎大家加入“专注Silverlight”QQ技术群,目前,1-6群都已经满员,新开500人七群,欢迎大家加入一起学习讨论Silverlight&WPF开发技术。  22308706(一群) 超级群500人满  37891947(二群) 超级群500人满  100844510(三群) 高级群200人满  32679922(四群) 超级群500人满  23413513(五群) 高级群200人满  32679955(六群) 超级群500人满  61267622(七群 推荐) 超级群500人未满  
';