【问题标题】:Get Validation Results获取验证结果
【发布时间】:2014-11-21 12:58:11
【问题描述】:

我正在使用带有 WPF 集成的 EntLib 6 验证块。 我的虚拟机中的简单属性:

    [StringLengthValidator(3, MessageTemplate = "Shorten me!")]
    public String SomeText
    {
        get { return _someText; }
        set
        {
            _someText = value;
            OnPropertyChanged("SomeText");
        }
    }

和一个对应的绑定到一个TextBox:

<TextBox ToolTip="{Binding (Validation.Errors).CurrentItem.ErrorContent, RelativeSource={x:Static RelativeSource.Self}}" 
         Text="{Binding SomeText, UpdateSourceTrigger=PropertyChanged}" 
         vab:Validate.BindingForProperty="Text"/>

如果您在 TextBox 中输入了三个以上的字符,则该值将被拒绝并存储最后一个有效字符。文本框以红色突出显示,相应的消息显示为工具提示。

在 VM 中,我想检查是否有任何验证错误 - 但由于该值在视图中被拒绝,所以一切似乎都很好。那么如何判断是否存在验证错误呢?

注意: VAB 不使用 IDataErrorInfo 接口!

【问题讨论】:

    标签: c# wpf validation enterprise-library


    【解决方案1】:

    当您使用 WPF 的内置验证 API 时,我不知道有一种简洁直接的方法可以从您的视图模型中获取验证结果。然而,虽然 VAB 可能不使用开箱即用的IDataErrorInfo,但您可以相当轻松地添加集成,并且您只需要修改基本视图模型类。你可以这样开始:

    public class ValidatingModel : INotifyPropertyChanged, IDataErrorInfo
    {
        private readonly Dictionary<string, PropertyInfo> _properties;
        private readonly Dictionary<string, Validator> _propertyValidators;
        private readonly Dictionary<string, ValidationResults> _validationResults;
    
        private string _compositeMessage;
    
        public ValidatingModel()
        {
            _properties = new Dictionary<string, PropertyInfo>();
            _propertyValidators = new Dictionary<string, Validator>();
            _validationResults = new Dictionary<string, ValidationResults>();
    
            PopulateValidators();
        }
    
        private void PopulateValidators()
        {
            var properties = GetType().GetProperties(
                BindingFlags.Instance |
                BindingFlags.Public);
    
            foreach (var property in properties)
            {
                var attributes = property.GetCustomAttributes(
                    typeof(ValueValidatorAttribute),
                    false);
    
                if (attributes.Length == 0 || _properties.ContainsKey(property.Name))
                    continue;
    
                _properties[property.Name] = property;
    
                _propertyValidators[property.Name] =
                    PropertyValidationFactory.GetPropertyValidatorFromAttributes(
                        property.PropertyType,
                        property,
                        string.Empty,
                        new MemberAccessValidatorBuilderFactory());
            }
        }
    
        protected IEnumerable<ValidationResult> GetValidationResults()
        {
            foreach (var results in _validationResults.Values)
            {
                foreach (var result in results)
                    yield return result;
            }
        }
    
        protected IEnumerable<ValidationResult> GetValidationResults(string property)
        {
            if (_propertyValidators.ContainsKey(property))
            {
                ValidationResults results;
    
                if (!_validationResults.TryGetValue(property, out results))
                    Validate(property);
    
                if (!_validationResults.TryGetValue(property, out results))
                    yield break;
    
                foreach (var result in results)
                    yield return result;
            }
        }
    
        protected void Validate(string propertyName)
        {
            if (_propertyValidators.ContainsKey(propertyName))
            {
                _compositeMessage = null;
                _validationResults[propertyName] = Validation.Validate(this);
            }
        }
    
        string IDataErrorInfo.this[string columnName]
        {
            get
            {
                ValidationResults results;
    
                if (!_validationResults.TryGetValue(columnName, out results))
                    Validate(columnName);
    
                if (_validationResults.TryGetValue(columnName, out results))
                    return CombineMessages(results);
    
                return null;
            }
        }
    
        string IDataErrorInfo.Error
        {
            get
            {
                if (_compositeMessage != null)
                    return _compositeMessage;
    
                foreach (var validator in _propertyValidators)
                {
                    if (_validationResults.ContainsKey(validator.Key))
                        continue;
    
                    _validationResults[validator.Key] = ValidateProperty(
                        validator.Value,
                        _properties[validator.Key]);
                }
    
                _compositeMessage = CombineMessages(
                    _validationResults.SelectMany(r => r.Value));
    
                return _compositeMessage;
            }
        }
    
        private ValidationResults ValidateProperty(
            Validator validator,
            PropertyInfo propertyInfo)
        {
            return validator.Validate(propertyInfo.GetValue(this, null));
        }
    
        private static string CombineMessages(IEnumerable<ValidationResult> results)
        {
            return results.Aggregate(
                new StringBuilder(),
                (sb, p) => (sb.Length > 0 ? sb.AppendLine() : sb).Append(p.Message),
                sb => sb.ToString());
        }
    
        protected void OnPropertyChanged(string propertyName)
        {
            Validate(propertyName);
    
            var handler = this.PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    }
    

    此视图模型在属性更改时使用验证应用程序块 API 执行验证,并通过 IDataErrorInfo 报告结果。您需要在 Binding 声明中设置 ValidatesOnDataErrors 才能使其正常工作。

    【讨论】:

    • vab 阻止绑定将无效值传递给 VM - 无论是否启用 ValidatesOnDataErrors
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    相关资源
    最近更新 更多