zoukankan      html  css  js  c++  java
  • WPF ValidationRules(MVVM 数据验证)

    对于WPF中的验证, View验证实现起来很简单, 可以通道 Validation.ErrorEvent 冒泡传递到View的逻辑树上, 只是, 通常这样做的情况下, 我们需要为View添加事件代码监听这类错误事件, 然后进行处理。
    这样做可以说是非常简单, 但是这样的硬编码的, 基本上每个模块每个功能, 你都必不可少的为其进行重复的工作, 这是一项非常枯燥且无聊的体力活!
    于是, 则考虑MVVM的架构中, 如何把这种模式传递到ViewModel中, 使得前端的验证, 对于ViewModel仍然有效。
    实现的原理, 如图所示:

    在此之前, 对于View前端验证需要做的一些操作步骤,

    • 1.为验证的属性添加自定义验证类
    • 2.设置验证错误的通知属性 NotifyOnValidationError="True" 。 注: 如此一来, 则可以产生Validation.ErrorEvent事件
    • 3.通过自定义的 ValidationExceptionBehavior 继承于 Behavior, 用于监听 Validation.ErrorEvent 的错误事件。
    • 4.在 ValidationExceptionBehavior 中通过 AssociatedObjectde的DataContex获取到关联当前View的DataContex, 从而改变DataContext的后端验证条件。

    1.设置属性自定义的验证类并添加 NotifyOnValidationError="True" 属性

                            <TextBox  Margin="15 0 10 0" 
                                     Style="{StaticResource MaterialDesignFloatingHintTextBox}"  materialDesign:HintAssist.Hint="登录名 *">
                                <TextBox.Text>
                                    <Binding Path="Model.Account" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
                                        <Binding.ValidationRules>
                                            <domain:CustomizeValidationRule validationType="Str" 
                                                                            minLength="3" maxLength="10"
                                                                            errorMessage="输入长度范围 [3-10]字" 
                                                                            ValidatesOnTargetUpdated="True" />
                                        </Binding.ValidationRules>
                                    </Binding>
                                </TextBox.Text>
                            </TextBox>
    

    2.自定义 IValidationExceptionHandler 接口, ViewModel继承IValidationExceptionHandler , 用于接收前端的验证结果。

    public interface IValidationExceptionHandler
        {
            /// <summary>
            /// 是否有效
            /// </summary>
            bool IsValid
            {
                get;
                set;
            }
        }
    

    3. 自定义 ValidationExceptionBehavior, 用于监听处理View的错误事件

        /// <summary>
        /// 验证行为类,可以获得附加到的对象
        /// </summary>
        public class ValidationExceptionBehavior : Behavior<FrameworkElement>
        {
            /// <summary>
            /// 错误计数器
            /// </summary>
            private int _validationExceptionCount = 0;
            
            /// <summary>
            /// 附加对象时
            /// </summary>
            protected override void OnAttached()
            {
                //附加对象时,给对象增加一个监听验证错误事件的能力,注意该事件是冒泡的
                this.AssociatedObject.AddHandler(Validation.ErrorEvent, new EventHandler<ValidationErrorEventArgs>(this.OnValidationError));
            }
            
            #region 获取实现接口的对象
    
            /// <summary>
            /// 获取对象
            /// </summary>
            /// <returns></returns>
            private IValidationExceptionHandler GetValidationExceptionHandler()
            {
                if (this.AssociatedObject.DataContext is IValidationExceptionHandler)
                {
                    var handler = this.AssociatedObject.DataContext as IValidationExceptionHandler;
    
                    return handler;
                }
    
                return null;
            }
    
            #endregion
            
            #region 验证事件方法
    
            /// <summary>
            /// 验证事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void OnValidationError(object sender, ValidationErrorEventArgs e)
            {
                try
                {
                    var handler = GetValidationExceptionHandler();
    
                    var element = e.OriginalSource as UIElement;
    
                    if (handler == null || element == null)
                        return;
    
                    if (e.Action == ValidationErrorEventAction.Added)
                    {
                        _validationExceptionCount++;
                        
                    }
                    else if (e.Action == ValidationErrorEventAction.Removed)
                    {
                        _validationExceptionCount--;
                    }
                    handler.IsValid = _validationExceptionCount == 0;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
    
            #endregion
        }
    
    

    4. View容器最外层注册添加的监听错误事件 ValidationExceptionBehavior

       <i:Interaction.Behaviors>
            <domain:ValidationExceptionBehavior></domain:ValidationExceptionBehavior>
        </i:Interaction.Behaviors>
    

    5. ViewModel 通过实现 IValidationExceptionHandler 来获取前端的验证结果

    根据前端验证的结果, 正确保存, 错误进行提示

            public override void Save()
            {
                if (!this.IsValid)
                {
                    MessageBox.Show("输入的格式有误,请重新输入!");
                    return;
                }
                base.Save();
            }
    

    效果:

  • 相关阅读:
    rhel 6.4 + udev+ 11.2.0.3 + gi + asm+ rac 双节点安装
    rhel 6.4 + udev + 11.2.0.3 + asm 单点安装
    vmware 中linux虚拟机动态添加硬盘
    flashback drop
    flashback query
    11g crsctl start/stop crs 和 crsctl start/stop cluster 的关系
    10g crs 启动报错的记录
    检测数据库日志的切换频率及归档文件大小的sql
    用widthStep的方法来增加某范围的像素----与imageROI对比
    用imageROI来增加某范围的像素
  • 原文地址:https://www.cnblogs.com/zh7791/p/11432827.html
Copyright © 2011-2022 走看看