WPF ValidationRules(MVVM 数据验证)

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

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

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

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

                        
                            
                                
                                    
                                        
                                    
                                
                            
                        

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

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

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

    /// 
    /// 验证行为类,可以获得附加到的对象
    /// 
    public class ValidationExceptionBehavior : Behavior
    {
        /// 
        /// 错误计数器
        /// 
        private int _validationExceptionCount = 0;
        
        /// 
        /// 附加对象时
        /// 
        protected override void OnAttached()
        {
            //附加对象时,给对象增加一个监听验证错误事件的能力,注意该事件是冒泡的
            this.AssociatedObject.AddHandler(Validation.ErrorEvent, new EventHandler(this.OnValidationError));
        }
        
        #region 获取实现接口的对象

        /// 
        /// 获取对象
        /// 
        /// 
        private IValidationExceptionHandler GetValidationExceptionHandler()
        {
            if (this.AssociatedObject.DataContext is IValidationExceptionHandler)
            {
                var handler = this.AssociatedObject.DataContext as IValidationExceptionHandler;

                return handler;
            }

            return null;
        }

        #endregion
        
        #region 验证事件方法

        /// 
        /// 验证事件
        /// 
        /// 
        /// 
        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

   
        
    

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

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

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

效果:
WPF ValidationRules(MVVM 数据验证)_第2张图片

转载于:https://www.cnblogs.com/zh7791/p/11432827.html

你可能感兴趣的:(WPF ValidationRules(MVVM 数据验证))