WPF ValidationRules (MVVM data validation)

For WPF validation, verification View is simple to implement, can be passed to the logical channel Validation.ErrorEvent bubble tree View, but, to do so is usually the case, we need to add an event monitor this type of error code View events and then processed.
Doing so can be very simple, but such hard-coded, basically every function of each module, you are essential to its repetitive work, this is a very tedious and boring manual labor!
Thus, consider MVVM architecture, how this pattern is transmitted to the ViewModel, so that the front end of the authentication, are still valid for ViewModel.
Realization of the principle, as shown:

Prior to this, the front end for validation View to do some of the steps,

  • 1. Add custom validation attribute class verification
  • 2. Set the validation error notification attribute NotifyOnValidationError = "True". Note: In this way, you can generate Validation.ErrorEvent event
  • 3. By custom ValidationExceptionBehavior inherited Behavior, for the error event listener Validation.ErrorEvent.
  • 4. In the DataContex ValidationExceptionBehavior by AssociatedObjectde acquired DataContex View associated with the current, thereby changing the rear end of the DataContext verification.

1. Set the custom validation attribute class and add NotifyOnValidationError = "True" Properties

                        <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. Custom interfaces IValidationExceptionHandler, ViewModel inheriting IValidationExceptionHandler, for receiving the front end of the verification result.

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

3. custom error event ValidationExceptionBehavior, for monitoring the processing of 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 the outermost vessel registered to add event listeners error ValidationExceptionBehavior

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

5. ViewModel acquired verification result achieved by the front end IValidationExceptionHandler

According to the results of the validation front, saved correctly, an error prompt

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

effect:

Guess you like

Origin www.cnblogs.com/zh7791/p/11432827.html