wpf表单验证

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

Silverlifgt版本:

public class ValidationScope
    {
        public FrameworkElement ScopeElement { get; private set; }

        private readonly ObservableCollection<ValidationError> _errors = new ObservableCollection<ValidationError>();

        public ObservableCollection<ValidationError> Errors
        {
            get { return _errors; }
        }

        public bool IsValid()
        {
            return _errors.Count == 0;
        }

        public static string GetValidateBoundProperty(DependencyObject obj)
        {
            return (string)obj.GetValue(ValidateBoundPropertyProperty);
        }

        public static void SetValidateBoundProperty(DependencyObject obj, string value)
        {
            obj.SetValue(ValidateBoundPropertyProperty, value);
        }

        public static readonly DependencyProperty ValidateBoundPropertyProperty =
            DependencyProperty.RegisterAttached("ValidateBoundProperty", typeof(string), typeof(ValidationScope), new PropertyMetadata(null));

        public static ValidationScope GetValidationScope(DependencyObject obj)
        {
            return (ValidationScope)obj.GetValue(ValidationScopeProperty);
        }

        public static void SetValidationScope(DependencyObject obj, ValidationScope value)
        {
            obj.SetValue(ValidationScopeProperty, value);
        }

        public static readonly DependencyProperty ValidationScopeProperty =
            DependencyProperty.RegisterAttached("ValidationScope", typeof(ValidationScope), typeof(ValidationScope), new PropertyMetadata(null, ValidationScopeChanged));

        private static void ValidationScopeChanged(DependencyObject source, DependencyPropertyChangedEventArgs args)
        {
            ValidationScope oldScope = args.OldValue as ValidationScope;
            if (oldScope != null)
            {
                oldScope.ScopeElement.BindingValidationError -= oldScope.ScopeElement_BindingValidationError;
                oldScope.ScopeElement = null;
            }

            FrameworkElement scopeElement = source as FrameworkElement;
            if (scopeElement == null)
            {
                throw new ArgumentException(string.Format(
                    "‘{0}‘ is not a valid type.ValidationScope attached property can only be specified on types inheriting from FrameworkElement.",
                    source));
            }

            ValidationScope newScope = (ValidationScope)args.NewValue;
            newScope.ScopeElement = scopeElement;
            newScope.ScopeElement.BindingValidationError += newScope.ScopeElement_BindingValidationError;
        }

        private void ScopeElement_BindingValidationError(object sender, ValidationErrorEventArgs e)
        {
            if (e.Action == ValidationErrorEventAction.Removed)
            {
                Errors.Remove(e.Error);
            }
            else if (e.Action == ValidationErrorEventAction.Added)
            {
                Errors.Add(e.Error);
            }
        }

        public void ValidateScope()
        {
            ForEachElement(ScopeElement, delegate(DependencyObject obj)
            {
                string propertyName = GetValidateBoundProperty(obj);
                if (!string.IsNullOrEmpty(propertyName))
                {
                    FrameworkElement element = (FrameworkElement)obj;
                    var field = element.GetType().GetFields(BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.Public)
                        .Where(p => p.FieldType == typeof(DependencyProperty) && p.Name == (propertyName + "Property"))
                        .FirstOrDefault();

                    if (field == null)
                    {
                        throw new ArgumentException(string.Format(
                            "Dependency property ‘{0}‘ could not be found on type ‘{1}‘; ValidationScope.ValidateBoundProperty",
                            propertyName, element.GetType()));
                    }
                    var be = element.GetBindingExpression((DependencyProperty)field.GetValue(null));
                    be.UpdateSource();
                }
            });
        }

        private static void ForEachElement(DependencyObject root, Action<DependencyObject> action)
        {
            int childCount = VisualTreeHelper.GetChildrenCount(root);
            for (int i = 0; i < childCount; i++)
            {
                var obj = VisualTreeHelper.GetChild(root, i);
                action(obj);
                ForEachElement(obj, action);
            }
        }
    }

  WPF版:

 public class ValidationScope
    {
        public FrameworkElement ScopeElement { get; private set; }

        private readonly ObservableCollection<ValidationError> _errors = new ObservableCollection<ValidationError>();

        public ObservableCollection<ValidationError> Errors
        {
            get { return _errors; }
        }

        public bool IsValid()
        {
            return _errors.Count == 0;
        }

        public static string GetValidateBoundProperty(DependencyObject obj)
        {
            return (string)obj.GetValue(ValidateBoundPropertyProperty);
        }

        public static void SetValidateBoundProperty(DependencyObject obj, string value)
        {
            obj.SetValue(ValidateBoundPropertyProperty, value);
        }

        public static readonly DependencyProperty ValidateBoundPropertyProperty =
            DependencyProperty.RegisterAttached("ValidateBoundProperty", typeof(string), typeof(ValidationScope), new PropertyMetadata(null));

        public static ValidationScope GetValidationScope(DependencyObject obj)
        {
            return (ValidationScope)obj.GetValue(ValidationScopeProperty);
        }

        public static void SetValidationScope(DependencyObject obj, ValidationScope value)
        {
            obj.SetValue(ValidationScopeProperty, value);
        }

        public static readonly DependencyProperty ValidationScopeProperty =
            DependencyProperty.RegisterAttached("ValidationScope", typeof(ValidationScope), typeof(ValidationScope), new PropertyMetadata(null, ValidationScopeChanged));

        private static void ValidationScopeChanged(DependencyObject source, DependencyPropertyChangedEventArgs args)
        {
            ValidationScope oldScope = args.OldValue as ValidationScope;
            if (oldScope != null)
            {
                oldScope.ScopeElement.RemoveHandler(System.Windows.Controls.Validation.ErrorEvent, new RoutedEventHandler(oldScope.ScopeElement_BindingValidationError));
                oldScope.ScopeElement = null;
            }

            FrameworkElement scopeElement = source as FrameworkElement;
            if (scopeElement == null)
            {
                throw new ArgumentException(string.Format(
                    "‘{0}‘ is not a valid type.ValidationScope attached property can only be specified on types inheriting from FrameworkElement.",
                    source));
            }

            ValidationScope newScope = (ValidationScope)args.NewValue;
            newScope.ScopeElement = scopeElement;
            newScope.ScopeElement.AddHandler(System.Windows.Controls.Validation.ErrorEvent, new RoutedEventHandler(newScope.ScopeElement_BindingValidationError), true);
        }

        public void ScopeElement_BindingValidationError(object sender, RoutedEventArgs e)
        {
            System.Windows.Controls.ValidationErrorEventArgs args = e as System.Windows.Controls.ValidationErrorEventArgs;

            if (args.Error.RuleInError is System.Windows.Controls.ValidationRule)
            {
                BindingExpression bindingExpression = args.Error.BindingInError as System.Windows.Data.BindingExpression;

                string propertyName = bindingExpression.ParentBinding.Path.Path;
                DependencyObject OriginalSource = args.OriginalSource as DependencyObject;

                string errorMessage = "";
                ReadOnlyObservableCollection<System.Windows.Controls.ValidationError> errors = System.Windows.Controls.Validation.GetErrors(OriginalSource);
                if (errors.Count > 0)
                {
                    StringBuilder builder = new StringBuilder();
                    builder.Append(propertyName).Append(":");
                    System.Windows.Controls.ValidationError error = errors[errors.Count - 1];
                    {
                        if (error.Exception == null || error.Exception.InnerException == null)
                            builder.Append(error.ErrorContent.ToString());
                        else
                            builder.Append(error.Exception.InnerException.Message);
                    }
                    errorMessage = builder.ToString();
                }

                StringBuilder errorID = new StringBuilder();
                errorID.Append(args.Error.RuleInError.ToString());
                if (args.Action == ValidationErrorEventAction.Added)
                {
                    Errors.Add(args.Error);
                }
                else if (args.Action == ValidationErrorEventAction.Removed)
                {
                    Errors.Remove(args.Error);
                }

            }
        }

        public void ValidateScope()
        {
            ForEachElement(ScopeElement, delegate(DependencyObject obj)
            {
                string propertyName = GetValidateBoundProperty(obj);
                if (!string.IsNullOrEmpty(propertyName))
                {
                    FrameworkElement element = (FrameworkElement)obj;
                    var field = element.GetType().GetFields(BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.Public)
                        .Where(p => p.FieldType == typeof(DependencyProperty) && p.Name == (propertyName + "Property"))
                        .FirstOrDefault();

                    if (field == null)
                    {
                        throw new ArgumentException(string.Format(
                            "Dependency property ‘{0}‘ could not be found on type ‘{1}‘; ValidationScope.ValidateBoundProperty",
                            propertyName, element.GetType()));
                    }
                    var be = element.GetBindingExpression((DependencyProperty)field.GetValue(null));
                    be.UpdateSource();
                }
            });
        }

        private static void ForEachElement(DependencyObject root, Action<DependencyObject> action)
        {
            int childCount = VisualTreeHelper.GetChildrenCount(root);
            for (int i = 0; i < childCount; i++)
            {
                var obj = VisualTreeHelper.GetChild(root, i);
                action(obj);
                ForEachElement(obj, action);
            }
        }
    }

  

时间: 2024-10-15 09:44:52

wpf表单验证的相关文章

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

表单验证是MVVM体系中的重要一块.而绑定除了推动 Model-View-ViewModel (MVVM) 模式松散耦合 逻辑.数据 和 UI定义 的关系之外,还为业务数据验证方案提供强大而灵活的支持. WPF 中的数据绑定机制包括多个选项,可用于在创建可编辑视图时校验输入数据的有效性. 常见的表单验证机制有如下几种: 验证类型 说明 Exception 验证 通过在某个 Binding 对象上设置 ValidatesOnExceptions 属性,如果源对象属性设置已修改的值的过程中引发异常,

Xceed WPF表单输入控件Xceed Editors for WPF 免费下载及介绍

Xceed Editors for WPF 是一款包含12种功能强大的WPF编辑控件,用户输入控件,每个控件都具有多种风格主题,包含:日期选择控件.复选框.改进的TextBox.数字输入框.值范围输入框等. 具体功能: DatePicker/Calendar:日期选择控件 MaskedTextBox:为输入文本指定一种标记格式 CheckBox:提供了多种风格的复选框,不像传统的WPF复选框 AutoSelectTextBox:当控件具有焦点时内容被选择 ValueRangeTextBox:添加

C# WPF 表单更改提示

微信公众号:Dotnet9,网站:Dotnet9,问题或建议,请网站留言: 如果您觉得Dotnet9对您有帮助,欢迎赞赏 C# WPF 表单更改提示 内容目录 实现效果 业务场景 编码实现 本文参考 源码下载 1.实现效果 未做修改的表单展示 表单变化,关闭窗体提示 来个Gif动态操作看看 2.业务场景 表单修改后,关闭窗体前检查提示 3.编码实现 3.1 添加Nuget库 使用 .Net Core 3.1 创建名为"ValidateDataChange"的WPF解决方案,添加两个Nu

python :表单验证--对每一个输入框进行验证

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta charset="UTF-8"/> <title>Title</title> <style> .error{ color

jquery插件,表单验证validation plugin的使用

笔记: 一.首先引入插件 <script type="text/javascript" src="js/jquery-1.10.0.js" ></script> <script type="text/javascript" src="js/jquery.validate-1.13.1.js" ></script> 列子:一个简单的登录表单验证 1 <form id=&quo

AngularJs 表单验证

看到一些博客说这个框架要过时了,但是还是学习了下,觉的很方便的一个框架,有空的同学可以看看,适合我们入门看,比较基础. 对于日常的开发来说,最常见的开发场景就是通过表单编辑数据,这里涉及的问题就是验证问题. angularjs 内置已经支持了常见的验证方式,可以轻松实现表单验证. 1. 绑定 为了方便,我们在 $scope 上下文对象上创建一个 model 来表示我们编辑的内容. $scope.model = { id : 8, name: "alice", email: "

表单验证&amp;lt;AngularJs&amp;gt;

经常使用的表单验证指令 1. 必填项验证 某个表单输入是否已填写,仅仅要在输入字段元素上加入HTML5标记required就可以: <input type="text" required />   2. 最小长度 验证表单输入的文本长度是否大于某个最小值,在输入字段上使用指令ng-minleng= "{number}": <input type="text" ng-minlength="5" /> 3.

AngularJS复习------表单验证

在AngularJS中能够将HTML5表单验证功能同自己的验证指令结合起来使用,这里介绍使用的核心功能. 使用表单验证,首先要确保表单的每个控件都有name属性 如果想要屏蔽浏览器对表单的默认验证行为,可以在表单元素上添加novalidate标记. 必填项:只需要在输入字段元素上添加HTML5标记 required即可 最小长度:在输入字段上使用AngularJS指令ng-minlength="{number}" 最大长度:在输入字段上使用AngularJS指令ng-maxlength

java 表单验证

1.思路:通过表单选择器,表单属性过滤器提取每个表单提交的值,进行验证 2.实现:javascript通过 onSubmit()事件,判断,返回值false不提交,返回true提交,jquery通过submit()事件 3.表单验证常用的方法和事件 a:事件 onblur 失去焦点, onfocus获得焦点 b:方法 blur() 移开焦点触发方法参数 focus() 在文本域中设置焦点 触发方法参数 select()选取文本域中的内容触发方法参数 4.正则表达式: a:定义 var reg =