WPF中的条件验证实现

WPF应用程序开发中,数据验证是一个重要的环节。本文将介绍如何利用属性和接口实现条件验证,确保用户输入满足特定条件。

WPF提供了多种数据验证方法,本文将展示如何通过实现IDataErrorInfo接口和扩展RangeAttribute来实现条件验证。

实现条件验证

条件验证指的是在某些条件下才触发的验证。例如,只有当用户勾选了某个复选框时,才需要验证另一个输入框的值。

首先,需要扩展RangeAttribute来支持条件验证。以下是RangeIfAttribute类的实现:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] [Conditional] public class RangeIfAttribute : RangeAttribute { private string _dependentProperty; public RangeIfAttribute(double minimum, double maximum, string dependentProperty) : base(minimum, maximum) { this._dependentProperty = dependentProperty; } public RangeIfAttribute(int minimum, int maximum, string dependentProperty) : base(minimum, maximum) { this._dependentProperty = dependentProperty; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var containerType = validationContext.ObjectInstance.GetType(); var field = containerType.GetProperty(this._dependentProperty); bool dependentvalue = (bool)field.GetValue(validationContext.ObjectInstance); if (dependentvalue) { return base.IsValid(value, validationContext); } return ValidationResult.Success; } }

这个类通过重写IsValid方法,实现了条件验证逻辑。

接下来,在ViewModel中使用RangeIfAttribute来装饰属性:

public class CandidateViewModel : ViewModelBase { private int _yearsOfExperience; private bool _isExperienced; [RangeIf(1, 100, "IsExperienced", ErrorMessage = "Years Of Experience must be greater than 0")] public int YearsOfExperience { get { return this._yearsOfExperience; } set { this._yearsOfExperience = value; } } public bool IsExperienced { get { return this._isExperienced; } set { this._isExperienced = value; this.OnPropertyChanged("YearsOfExperience"); } } }

这里,YearsOfExperience属性依赖于IsExperienced属性的值。只有当IsExperienced为true时,YearsOfExperience的值才需要在1到100之间。

为了支持条件验证,需要在ViewModelBase类中实现IDataErrorInfo接口:

public class ViewModelBase : IDataErrorInfo, INotifyPropertyChanged { private readonly Dictionary> propertyGetters; private readonly Dictionary validators; public ViewModelBase() { this.validators = this.GetType().GetProperties() .Where(p => this.GetValidations(p).Length != 0) .ToDictionary(p => p.Name, p => this.GetValidations(p)); this.propertyGetters = this.GetType().GetProperties() .Where(p => this.GetValidations(p).Length != 0) .ToDictionary(p => p.Name, p => this.GetValueGetter(p)); } public string this[string propertyName] { get { if (this.propertyGetters.ContainsKey(propertyName)) { var errorMessages = this.validators[propertyName] .Where(attribute => !this.Validate(attribute, propertyName)) .Select(attribute => attribute.ErrorMessage).ToList(); return string.Join(Environment.NewLine, errorMessages); } return string.Empty; } } private bool Validate(ValidationAttribute validationAttribute, string propertyName) { var propertyValue = this.propertyGetters[propertyName](this); if (IsConditionalValidationAttribute(validationAttribute)) { return validationAttribute.GetValidationResult(propertyValue, new ValidationContext(this)) == ValidationResult.Success; } return validationAttribute.IsValid(propertyValue); } private bool IsConditionalValidationAttribute(ValidationAttribute validationAttribute) { return validationAttribute.GetType().GetCustomAttributes().Any(x => x.GetType() == typeof(ConditionalAttribute)); } }

在这个类中,通过重写索引器来获取属性的验证错误信息。如果验证属性是条件验证属性,调用GetValidationResult方法来获取验证结果。

本文介绍了如何在WPF应用程序中实现条件验证。通过扩展RangeAttribute和实现IDataErrorInfo接口,可以轻松地为应用程序添加条件验证逻辑。这种方法不仅清晰,而且易于维护。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485