C# 获取验证结果

C# 获取验证结果,c#,wpf,validation,enterprise-library,C#,Wpf,Validation,Enterprise Library,我正在使用EntLib 6验证块与WPF集成。 我的虚拟机中的简单属性: [StringLengthValidator(3, MessageTemplate = "Shorten me!")] public String SomeText { get { return _someText; } set { _someText = value; OnPropertyChanged

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

    [StringLengthValidator(3, MessageTemplate = "Shorten me!")]
    public String SomeText
    {
        get { return _someText; }
        set
        {
            _someText = value;
            OnPropertyChanged("SomeText");
        }
    }
以及与文本框对应的绑定:

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

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

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


注意:VAB不使用IDataErrorInfo接口

当您使用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;
}
公共类验证模型:INotifyPropertyChanged,IDataErrorInfo
{
私有只读字典_属性;
私有只读字典_propertyValidators;
私有只读字典_validationResults;
私有字符串_复合消息;
公共验证模型()
{
_属性=新字典();
_propertyValidators=新字典();
_validationResults=新字典();
PopulateValidators();
}
私有void PopulateValidators()
{
var properties=GetType().GetProperties(
BindingFlags.Instance|
(公众),;
foreach(属性中的var属性)
{
var attributes=property.GetCustomAttributes(
类型(ValueValidator属性),
假);
if(attributes.Length==0 | | | u properties.ContainsKey(property.Name))
继续;
_属性[property.Name]=属性;
_propertyValidators[property.Name]=
PropertyValidationFactory.GetPropertyValidatorFromAttributes(
property.PropertyType,
财产,,
字符串。空,
新成员AccessValidatorBuilderFactory());
}
}
受保护的IEnumerable GetValidationResults()
{
foreach(var结果为_validationResults.Values)
{
foreach(结果中的var结果)
收益结果;
}
}
受保护的IEnumerable GetValidationResults(字符串属性)
{
如果(_propertyValidators.ContainsKey(property))
{
验证结果;
if(!\u validationResults.TryGetValue(属性,输出结果))
确认(财产);
if(!\u validationResults.TryGetValue(属性,输出结果))
屈服断裂;
foreach(结果中的var结果)
收益结果;
}
}
受保护的无效验证(字符串propertyName)
{
if(_propertyValidators.ContainsKey(propertyName))
{
_compositeMessage=null;
_validationResults[propertyName]=Validation.Validate(此);
}
}
字符串IDataErrorInfo。此[string columnName]
{
得到
{
验证结果;
if(!\u validationResults.TryGetValue(columnName,out results))
验证(列名称);
if(_validationResults.TryGetValue(columnName,out results))
返回组合消息(结果);
返回null;
}
}
字符串IDataErrorInfo.Error
{
得到
{
如果(_compositeMessage!=null)
返回_复合消息;
foreach(属性验证程序中的var验证程序)
{
if(_validationResults.ContainsKey(validator.Key))
继续;
_validationResults[validator.Key]=ValidateProperty(
验证器值,
_属性[validator.Key]);
}
_复合消息=组合消息(
_validationResults.SelectMany(r=>r.Value));
返回_复合消息;
}
}
私有验证结果验证属性(
验证器验证器,
PropertyInfo PropertyInfo)
{
返回validator.Validate(propertyInfo.GetValue(this,null));
}
私有静态字符串组合消息(IEnumerable结果)
{
返回结果。聚合(
新建StringBuilder(),
(sb,p)=>(sb.Length>0?sb.AppendLine():sb).Append(p.Message),
sb=>sb.ToString());
}
受保护的无效OnPropertyChanged(字符串propertyName)
{
验证(propertyName);
var handler=this.PropertyChanged;
if(处理程序!=null)
处理程序(这是新的PropertyChangedEventArgs(propertyName));
}
公共事件属性更改事件处理程序属性更改;
}

每当属性发生更改时,此视图模型使用验证应用程序块API执行验证,并通过
IDataErrorInfo
报告结果。您需要在
绑定
声明上设置
validatesOnDaerRors
,以使其生效。

vab防止绑定将无效值传递给VM—无论是否启用validatesOnDaerRors