在做表单的,需要对User提交数据做验证,wpf与silverlight 都提供自带的验证机制,但是只是验证,并不能在提交时提供详细的信息,此时可使用 依赖属性将错误信息整合进自定义错误集合中,即可在提交时获取相应错误信息方便后续业务处理。

Silverlifgt版本:

  1. public class ValidationScope
  2. {
  3. public FrameworkElement ScopeElement { get; private set; }
  4.  
  5. private readonly ObservableCollection<ValidationError> _errors = new ObservableCollection<ValidationError>();
  6.  
  7. public ObservableCollection<ValidationError> Errors
  8. {
  9. get { return _errors; }
  10. }
  11.  
  12. public bool IsValid()
  13. {
  14. return _errors.Count == 0;
  15. }
  16.  
  17. public static string GetValidateBoundProperty(DependencyObject obj)
  18. {
  19. return (string)obj.GetValue(ValidateBoundPropertyProperty);
  20. }
  21.  
  22. public static void SetValidateBoundProperty(DependencyObject obj, string value)
  23. {
  24. obj.SetValue(ValidateBoundPropertyProperty, value);
  25. }
  26.  
  27. public static readonly DependencyProperty ValidateBoundPropertyProperty =
  28. DependencyProperty.RegisterAttached("ValidateBoundProperty", typeof(string), typeof(ValidationScope), new PropertyMetadata(null));
  29.  
  30. public static ValidationScope GetValidationScope(DependencyObject obj)
  31. {
  32. return (ValidationScope)obj.GetValue(ValidationScopeProperty);
  33. }
  34.  
  35. public static void SetValidationScope(DependencyObject obj, ValidationScope value)
  36. {
  37. obj.SetValue(ValidationScopeProperty, value);
  38. }
  39.  
  40. public static readonly DependencyProperty ValidationScopeProperty =
  41. DependencyProperty.RegisterAttached("ValidationScope", typeof(ValidationScope), typeof(ValidationScope), new PropertyMetadata(null, ValidationScopeChanged));
  42.  
  43. private static void ValidationScopeChanged(DependencyObject source, DependencyPropertyChangedEventArgs args)
  44. {
  45. ValidationScope oldScope = args.OldValue as ValidationScope;
  46. if (oldScope != null)
  47. {
  48. oldScope.ScopeElement.BindingValidationError -= oldScope.ScopeElement_BindingValidationError;
  49. oldScope.ScopeElement = null;
  50. }
  51.  
  52. FrameworkElement scopeElement = source as FrameworkElement;
  53. if (scopeElement == null)
  54. {
  55. throw new ArgumentException(string.Format(
  56. "'{0}' is not a valid type.ValidationScope attached property can only be specified on types inheriting from FrameworkElement.",
  57. source));
  58. }
  59.  
  60. ValidationScope newScope = (ValidationScope)args.NewValue;
  61. newScope.ScopeElement = scopeElement;
  62. newScope.ScopeElement.BindingValidationError += newScope.ScopeElement_BindingValidationError;
  63. }
  64.  
  65. private void ScopeElement_BindingValidationError(object sender, ValidationErrorEventArgs e)
  66. {
  67. if (e.Action == ValidationErrorEventAction.Removed)
  68. {
  69. Errors.Remove(e.Error);
  70. }
  71. else if (e.Action == ValidationErrorEventAction.Added)
  72. {
  73. Errors.Add(e.Error);
  74. }
  75. }
  76.  
  77. public void ValidateScope()
  78. {
  79. ForEachElement(ScopeElement, delegate(DependencyObject obj)
  80. {
  81. string propertyName = GetValidateBoundProperty(obj);
  82. if (!string.IsNullOrEmpty(propertyName))
  83. {
  84. FrameworkElement element = (FrameworkElement)obj;
  85. var field = element.GetType().GetFields(BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.Public)
  86. .Where(p => p.FieldType == typeof(DependencyProperty) && p.Name == (propertyName + "Property"))
  87. .FirstOrDefault();
  88.  
  89. if (field == null)
  90. {
  91. throw new ArgumentException(string.Format(
  92. "Dependency property '{0}' could not be found on type '{1}'; ValidationScope.ValidateBoundProperty",
  93. propertyName, element.GetType()));
  94. }
  95. var be = element.GetBindingExpression((DependencyProperty)field.GetValue(null));
  96. be.UpdateSource();
  97. }
  98. });
  99. }
  100.  
  101. private static void ForEachElement(DependencyObject root, Action<DependencyObject> action)
  102. {
  103. int childCount = VisualTreeHelper.GetChildrenCount(root);
  104. for (int i = 0; i < childCount; i++)
  105. {
  106. var obj = VisualTreeHelper.GetChild(root, i);
  107. action(obj);
  108. ForEachElement(obj, action);
  109. }
  110. }
  111. }

  WPF版:

  1. public class ValidationScope
  2. {
  3. public FrameworkElement ScopeElement { get; private set; }
  4.  
  5. private readonly ObservableCollection<ValidationError> _errors = new ObservableCollection<ValidationError>();
  6.  
  7. public ObservableCollection<ValidationError> Errors
  8. {
  9. get { return _errors; }
  10. }
  11.  
  12. public bool IsValid()
  13. {
  14. return _errors.Count == 0;
  15. }
  16.  
  17. public static string GetValidateBoundProperty(DependencyObject obj)
  18. {
  19. return (string)obj.GetValue(ValidateBoundPropertyProperty);
  20. }
  21.  
  22. public static void SetValidateBoundProperty(DependencyObject obj, string value)
  23. {
  24. obj.SetValue(ValidateBoundPropertyProperty, value);
  25. }
  26.  
  27. public static readonly DependencyProperty ValidateBoundPropertyProperty =
  28. DependencyProperty.RegisterAttached("ValidateBoundProperty", typeof(string), typeof(ValidationScope), new PropertyMetadata(null));
  29.  
  30. public static ValidationScope GetValidationScope(DependencyObject obj)
  31. {
  32. return (ValidationScope)obj.GetValue(ValidationScopeProperty);
  33. }
  34.  
  35. public static void SetValidationScope(DependencyObject obj, ValidationScope value)
  36. {
  37. obj.SetValue(ValidationScopeProperty, value);
  38. }
  39.  
  40. public static readonly DependencyProperty ValidationScopeProperty =
  41. DependencyProperty.RegisterAttached("ValidationScope", typeof(ValidationScope), typeof(ValidationScope), new PropertyMetadata(null, ValidationScopeChanged));
  42.  
  43. private static void ValidationScopeChanged(DependencyObject source, DependencyPropertyChangedEventArgs args)
  44. {
  45. ValidationScope oldScope = args.OldValue as ValidationScope;
  46. if (oldScope != null)
  47. {
  48. oldScope.ScopeElement.RemoveHandler(System.Windows.Controls.Validation.ErrorEvent, new RoutedEventHandler(oldScope.ScopeElement_BindingValidationError));
  49. oldScope.ScopeElement = null;
  50. }
  51.  
  52. FrameworkElement scopeElement = source as FrameworkElement;
  53. if (scopeElement == null)
  54. {
  55. throw new ArgumentException(string.Format(
  56. "'{0}' is not a valid type.ValidationScope attached property can only be specified on types inheriting from FrameworkElement.",
  57. source));
  58. }
  59.  
  60. ValidationScope newScope = (ValidationScope)args.NewValue;
  61. newScope.ScopeElement = scopeElement;
  62. newScope.ScopeElement.AddHandler(System.Windows.Controls.Validation.ErrorEvent, new RoutedEventHandler(newScope.ScopeElement_BindingValidationError), true);
  63. }
  64.  
  65. public void ScopeElement_BindingValidationError(object sender, RoutedEventArgs e)
  66. {
  67. System.Windows.Controls.ValidationErrorEventArgs args = e as System.Windows.Controls.ValidationErrorEventArgs;
  68.  
  69. if (args.Error.RuleInError is System.Windows.Controls.ValidationRule)
  70. {
  71. BindingExpression bindingExpression = args.Error.BindingInError as System.Windows.Data.BindingExpression;
  72.  
  73. string propertyName = bindingExpression.ParentBinding.Path.Path;
  74. DependencyObject OriginalSource = args.OriginalSource as DependencyObject;
  75.  
  76. string errorMessage = "";
  77. ReadOnlyObservableCollection<System.Windows.Controls.ValidationError> errors = System.Windows.Controls.Validation.GetErrors(OriginalSource);
  78. if (errors.Count > 0)
  79. {
  80. StringBuilder builder = new StringBuilder();
  81. builder.Append(propertyName).Append(":");
  82. System.Windows.Controls.ValidationError error = errors[errors.Count - 1];
  83. {
  84. if (error.Exception == null || error.Exception.InnerException == null)
  85. builder.Append(error.ErrorContent.ToString());
  86. else
  87. builder.Append(error.Exception.InnerException.Message);
  88. }
  89. errorMessage = builder.ToString();
  90. }
  91.  
  92. StringBuilder errorID = new StringBuilder();
  93. errorID.Append(args.Error.RuleInError.ToString());
  94. if (args.Action == ValidationErrorEventAction.Added)
  95. {
  96. Errors.Add(args.Error);
  97. }
  98. else if (args.Action == ValidationErrorEventAction.Removed)
  99. {
  100. Errors.Remove(args.Error);
  101. }
  102.  
  103. }
  104. }
  105.  
  106. public void ValidateScope()
  107. {
  108. ForEachElement(ScopeElement, delegate(DependencyObject obj)
  109. {
  110. string propertyName = GetValidateBoundProperty(obj);
  111. if (!string.IsNullOrEmpty(propertyName))
  112. {
  113. FrameworkElement element = (FrameworkElement)obj;
  114. var field = element.GetType().GetFields(BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.Public)
  115. .Where(p => p.FieldType == typeof(DependencyProperty) && p.Name == (propertyName + "Property"))
  116. .FirstOrDefault();
  117.  
  118. if (field == null)
  119. {
  120. throw new ArgumentException(string.Format(
  121. "Dependency property '{0}' could not be found on type '{1}'; ValidationScope.ValidateBoundProperty",
  122. propertyName, element.GetType()));
  123. }
  124. var be = element.GetBindingExpression((DependencyProperty)field.GetValue(null));
  125. be.UpdateSource();
  126. }
  127. });
  128. }
  129.  
  130. private static void ForEachElement(DependencyObject root, Action<DependencyObject> action)
  131. {
  132. int childCount = VisualTreeHelper.GetChildrenCount(root);
  133. for (int i = 0; i < childCount; i++)
  134. {
  135. var obj = VisualTreeHelper.GetChild(root, i);
  136. action(obj);
  137. ForEachElement(obj, action);
  138. }
  139. }
  140. }

  

wpf表单验证的更多相关文章

  1. WPF权限控制——【3】数据库、自定义弹窗、表单验证

    你相信"物竞天择,适者生存"这样的学说吗?但是我们今天却在提倡"尊老爱幼,救死扶伤",帮助并救护弱势群体:第二次世界大战期间,希特勒认为自己是优等民族,劣势民族 ...

  2. 利刃 MVVMLight 5:绑定在表单验证上的应用

    表单验证是MVVM体系中的重要一块.而绑定除了推动 Model-View-ViewModel (MVVM) 模式松散耦合 逻辑.数据 和 UI定义 的关系之外,还为业务数据验证方案提供强大而灵活的支持 ...

  3. C# WPF 表单更改提示

    微信公众号:Dotnet9,网站:Dotnet9,问题或建议,请网站留言: 如果您觉得Dotnet9对您有帮助,欢迎赞赏 C# WPF 表单更改提示 内容目录 实现效果 业务场景 编码实现 本文参考 ...

  4. jQuery学习之路(8)- 表单验证插件-Validation

    ▓▓▓▓▓▓ 大致介绍 jQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求.该插件捆绑了一套有用的验证方法,包括 ...

  5. 玩转spring boot——AOP与表单验证

    AOP在大多数的情况下的应用场景是:日志和验证.至于AOP的理论知识我就不做赘述.而AOP的通知类型有好几种,今天的例子我只选一个有代表意义的“环绕通知”来演示. 一.AOP入门 修改“pom.xml ...

  6. form表单验证-Javascript

    Form表单验证: js基础考试内容,form表单验证,正则表达式,blur事件,自动获取数组,以及css布局样式,动态清除等.完整代码如下: <!DOCTYPE html PUBLIC &qu ...

  7. ASP.NET MVC5+EF6+EasyUI 后台管理系统(33)-MVC 表单验证

    系列目录 注:本节阅读需要有MVC 自定义验证的基础,否则比较吃力 一直以来表单的验证都是不可或缺的,微软的东西还是做得比较人性化的,从webform到MVC,都做到了双向验证 单单的用js实现的前端 ...

  8. 实现跨浏览器html5表单验证

    div:nth-of-type(odd){ float: left; clear: left; } .origin-effect > div:nth-of-type(even){ float: ...

  9. jQuery Validate 表单验证 — 用户注册简单应用

    相信很多coder在表单验证这块都是自己写验证规则的,今天我们用jQuery Validate这款前端验证利器来写一个简单的应用. 可以先把我写的这个小demo运行试下,先睹为快.猛戳链接--> ...

随机推荐

  1. ThinkPhp5 中Volist标签的用法

    Volist标签一般是和内置方法assign()搭配使用,将值从后台传到前台,是当下比较流行的一种传值方法 本文实例讲述了ThinkPHP模板循环输出Volist标签用法.分享给大家供大家参考,具体如 ...

  2. 随机获取list或set或map中的一个元素

    转自:https://m.2cto.com/kf/201507/412937.html import java.util.HashSet;import java.util.List;import ja ...

  3. 非分页中的上一篇下一篇sql语句如何写

    上一页:where id=(select max(id) from examination where id < #{id} and class=#{class}) 下一页:where id=( ...

  4. go基础_控制语句

    if控制语句 说明:(1)if后面的条件语句不用加括号 (2)if后面可以跟一个简单的初始化语句,并以分号分割,初始化语句中的变量的作用域是整个if语句块 (3)if语句的条件语句需要尽量简单 (4) ...

  5. [洛谷P4463] calc (生成函数)

    首先注意到题目中 \(a\) 数组是有序的,那我们只用算有序的方案乘上 \(n!\) 即可. 而此时的答案显然 \[Ans=[x^n](1+x)(1+2x)\dots (1+Ax)=\prod_{i= ...

  6. webRTC中回声消除(AEC)模块编译时aec_rdft.c文件报错:

    webRTC中回声消除(AEC)模块编译时aec_rdft.c文件报错. 原因是: 局部变量ip跟全局变量冲突的问题,可以将局部变量重新命名一下,就可以通过编译了. aec_rdft.c修改以后文件代 ...

  7. 隐藏pyqt中调用matplotlib图片中的工具栏

    方法: # pyqtgraph使用matplotlib import pyqtgraph.widgets.MatplotlibWidget as mw a_plt = mw.MatplotlibWid ...

  8. sshpass远程登陆

    1,ssh ssh 端口为默认22的时候: sshpass -p 888888 scp -o StrictHostKeyChecking=no /root/images.zip root@21.1.9 ...

  9. 「CSP-S模拟赛」2019第一场

    目录 T1 小奇取石子 题目 考场思路 正解 T2 「CCO 2017」专业网络 题目 考场思路 题解 T3 「ZJOI2017」线段树 题目 考场思路 正解 这场考试感觉很奇怪. \(T1.T2\) ...

  10. Flutter Android 真机器调试 、模拟器调试、Vscode 中开发 Flutter 应用

    必备条件: 1.准备一台 Android 手机 2.手机需要开启调试模式 3.用数据线把手机连上电脑 4.手机要允许电脑进行 Usb 调试 5.手机对应的 sdk 版本必须安装 注意: 1.关闭电脑上 ...