INotifyDataErrorInfo не имеет ничего общего с поездками в БД (или вызовами через границу службы, что, как я полагаю, вы имели в виду).INotifyDataErrorInfo - это интерфейс, который вы можете реализовать в модели представления, чтобы сообщить вашему представлению, что ваша модель представления имеет ошибки проверки.Завершение проверки вашей модели представления для использования этого интерфейса по-прежнему остается за вами, если только это не то, что службы WCF RIA предоставляют вам бесплатно, в чем я не уверен.
Я использую атрибут [Требуется]на мой взгляд, модели только для того, чтобы дать подсказку пользовательскому интерфейсу, что мои поля обязательны для заполнения.Я также реализую INotifyDataErrorInfo в моей модели представления и обязательно вызываю мой метод проверки всякий раз, когда изменяются какие-либо свойства в модели представления.Я также вручную вызываю мой метод проверки, когда пользователь выполняет команду сохранения.
В моем случае я использую библиотеку Fluent Validation для реализации моей логики проверки.Я также создал новый базовый класс для любых моделей представлений, которые нуждаются в логике проверки.
public class ValidatingViewModelBase<T> : ViewModelBase, IValidatingViewModel, INotifyDataErrorInfo
{
private readonly IValidator<T> _validator;
private readonly Dictionary<string, List<ValidationInfo>> _errors;
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public ValidatingViewModelBase() : this(null, null)
{
}
public ValidatingViewModelBase(IValidator<T> validator) : this(validator, null)
{
}
public ValidatingViewModelBase(IValidator<T> validator, IMessenger messenger) : base(messenger)
{
_validator = validator;
_errors = new Dictionary<string, List<ValidationInfo>>();
}
public IEnumerable GetErrors(string propertyName)
{
if (string.IsNullOrEmpty(propertyName))
return _errors.Values;
CreateValidationErrorInfoListForProperty(propertyName);
return _errors[propertyName];
}
public bool HasErrors
{
get { return _errors.Count > 0; }
}
protected virtual void AddValidationErrorForProperty(string propertyName, ValidationInfo validationInfo)
{
CreateValidationErrorInfoListForProperty(propertyName);
if (!_errors[propertyName].Contains(validationInfo))
{
_errors[propertyName].Add(validationInfo);
RaiseErrorsChanged(propertyName);
}
}
protected virtual void ClearValidationErrorsForProperty(string propertyName)
{
CreateValidationErrorInfoListForProperty(propertyName);
if (_errors[propertyName].Count > 0)
{
_errors[propertyName].Clear();
RaiseErrorsChanged(propertyName);
}
}
protected virtual void ClearAllValidationErrors()
{
foreach (var propertyName in _errors.Keys)
ClearValidationErrorsForProperty(propertyName);
_errors.Clear();
}
private void CreateValidationErrorInfoListForProperty(string propertyName)
{
if (!_errors.ContainsKey(propertyName))
_errors[propertyName] = new List<ValidationInfo>();
}
protected void RaiseErrorsChanged(string propertyName)
{
var handler = ErrorsChanged;
if (handler != null)
{
handler.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
}
}
protected override void RaisePropertyChanged(string propertyName)
{
Validate();
base.RaisePropertyChanged(propertyName);
}
public bool Validate()
{
if (_validator == null)
return true;
if (this is ILoadAndSaveData && !((ILoadAndSaveData)this).HasLoadedData)
return true;
ClearAllValidationErrors();
var results = _validator.Validate(this);
if (!results.IsValid)
{
foreach (var failure in results.Errors)
{
AddValidationErrorForProperty(failure.PropertyName,
new ValidationInfo(failure.ErrorMessage, ValidationType.Error));
}
}
return results.IsValid;
}
public void SendValidationMessage()
{
var message = _errors.Values.SelectMany(propertyValidations => propertyValidations)
.Aggregate("Please correct validation errors before saving.\r\n",
(current, validationInfo) => current + ("\r\n· " + validationInfo.Message));
MessengerInstance.Send(new ErrorMessage(new ErrorInfo { Message = message, Type = "Validation Error" }));
}
public bool ValidateAndSendValidationMessage()
{
var isValid = Validate();
if (!isValid)
{
SendValidationMessage();
}
return isValid;
}
}
public interface IValidatingViewModel
{
bool Validate();
void SendValidationMessage();
bool ValidateAndSendValidationMessage();
}
public enum ValidationType { Error, Warning }
public class ValidationInfo
{
public string Message { get; set; }
public ValidationType Type { get; set; }
public ValidationInfo(string message, ValidationType validationType)
{
Message = message;
Type = validationType;
}
public override string ToString()
{
var result = Message;
if (Type == ValidationType.Warning)
result = "Warning: " + result;
return result;
}
}
Так что мои модели представлений наследуют от этого нового базового класса.создайте класс валидатора для каждой модели представления.
public class ExampleValidator : AbstractValidator<IExampleViewModel>
{
public TripInformationValidator()
{
// validation logic here
}
}
Надеюсь, это поможет!