zoukankan      html  css  js  c++  java
  • 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);
                }
            }
        }
    

      

  • 相关阅读:
    面向对象诠释图
    vs中web网站和web应用程序的区别
    基于Windows Mobile 5.0的GPS应用程序开发
    c#添加水印效果
    基于Silverlight4开发的相关工具
    WCF、Net remoting、Web service概念及区别
    数据库的相关经验总结
    SQLite 3 一些基本的使用
    PPC上网设置明细图文并茂
    正则表达式语法参考
  • 原文地址:https://www.cnblogs.com/CoreXin/p/5056204.html
Copyright © 2011-2022 走看看