Когда мы проверяем свойство, не просматривая его.Он не будет обновлять свойство Validate.HasError элемента управления.Решением этой проблемы было простое старое простое NotifyPropertyChanged (propertyName).
Я использовал NotifyPropertyChanged
, когда значение моего свойства изменяется (в наборе), но без его обхода оно никогда не срабатывает.
Так что либо мы должны вызвать NotifyPropertyChanged
, когда проверка свойства не удалась, либо мы должны вызвать NotifyPropertyChanged(null)
, который уведомляет все элементы управления о необходимости обновить их свойства.
Добавление полной реализации моего INotifyDataErrorInfo
public class NotifyDataErrorInfoBase<T> : INotifyDataErrorInfo
{
public NotifyDataErrorInfoBase(T model)
{
Model = model;
}
public T Model { get; set; }
protected void SetValue<TValue>(string propertyName, TValue value)
{
typeof(T).GetProperty(propertyName).SetValue(Model, value);
ValidateProperty<TValue>(propertyName);
}
public bool ValidateAllProperties()
{
List<KeyValuePair<string, Type>> lstOfProperties = typeof(T).GetProperties().
Select(u => new KeyValuePair<string, Type>(u.Name, u.PropertyType)).ToList();
foreach (var property in lstOfProperties)
{
Type currentType = property.Value;
if (property.Value == typeof(string))
{
ValidateProperty<string>(property.Key);
}
else if (property.Value == typeof(int))
{
ValidateProperty<int>(property.Key);
}
}
return !HasErrors;
}
private void ValidateProperty<TValue>([CallerMemberName]string propertyName = null)
{
ClearErrors(propertyName);
var validationContext = new ValidationContext(Model) { MemberName = propertyName };
List<ValidationResult> results = new List<ValidationResult>();
var userName = GetValue<TValue>(propertyName);
Validator.TryValidateProperty(userName, validationContext, results);
if (results.Any())
{
foreach (var item in results)
{
AddError(propertyName, item.ErrorMessage);
}
}
}
protected TValue GetValue<TValue>(string propertyName)
{
return (TValue)typeof(T).GetProperty(propertyName).GetValue(Model);
}
Dictionary<string, List<string>> _lstOfErrors = new Dictionary<string, List<string>>();
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public bool HasErrors => _lstOfErrors.Any();
public IEnumerable GetErrors(string propertyName)
{
return _lstOfErrors.ContainsKey(propertyName) ? _lstOfErrors[propertyName] : null;
}
protected void AddError(string propertyName, string errorMessage)
{
if (!_lstOfErrors.ContainsKey(propertyName))
{
_lstOfErrors[propertyName] = new List<string>();
}
_lstOfErrors[propertyName].Add(errorMessage);
}
protected void OnErrorsChanged(string propertyName)
{
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
}
protected void ClearErrors(string propertyName)
{
if (_lstOfErrors.ContainsKey(propertyName))
_lstOfErrors.Remove(propertyName);
}
}