WPF - Как реализовать интерфейс IDataErrorInfo для сложной модели во ViewModel (FluentValidation) - PullRequest
0 голосов
/ 17 мая 2019

Я думаю, что моя проблема довольно проста для описания - так как я использую подход базы данных в первую очередь с использованием EF - я определенно не хочу иметь никакого дополнительного кода в моих классах Model, потому что он исчезает при обновлении базы данных в файле edmx (и будетне зависит от EF).

Я не хочу, чтобы в моей ViewModel было много свойств, таких же, как в модели, поэтому я всегда использую сложные типы, например, скажем, Customer

    public partial class Customer
    {

        public int ID{ get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
}

public class AddCustomerViewModel:ViewModelBase
{
        public Customer Customer
        {
            get { return customer; }
            set { customer = value; RaisePropertyChanged(); }
        }
}

Как проверить класс Customer во ViewModel, используя IDataErrorInfo и CustomerValidator (FluentValidation Framework) - или другим способом, используя DataAnnotation - без какого-либо дополнительного кода в модели Customer.

Заранее спасибо за указание способа решенияэта проблема!

1 Ответ

0 голосов
/ 17 мая 2019

Вы можете обернуть модель и реализовать логику проверки в модели представления:

public class AddCustomerViewModel : ViewModelBase, INotifyDataErrorInfo
{
    private readonly Dictionary<string, ICollection<string>> _validationErrors 
        = new Dictionary<string, ICollection<string>>();
    private readonly Customer _customer;

    public AddCustomerViewModel(Customer customer)
    {
        _customer = customer;
    }

    [Required(ErrorMessage = "You must enter a name.")]
    public string Name
    {
        get { return _customer.Name; }
        set { _customer.Name = value; ValidateModelProperty(value, nameof(Name)); }
    }

    //+ ID and Address

    private void ValidateModelProperty(object value, string propertyName)
    {
        if (_validationErrors.ContainsKey(propertyName))
            _validationErrors.Remove(propertyName);

        ICollection<ValidationResult> validationResults = new List<ValidationResult>();
        ValidationContext validationContext =
            new ValidationContext(this, null, null) { MemberName = propertyName };
        if (!Validator.TryValidateProperty(value, validationContext, validationResults))
        {
            _validationErrors.Add(propertyName, new List<string>());
            foreach (ValidationResult validationResult in validationResults)
            {
                _validationErrors[propertyName].Add(validationResult.ErrorMessage);
            }
        }
        RaiseErrorsChanged(propertyName);
    }

    #region INotifyDataErrorInfo members
    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
    private void RaiseErrorsChanged(string propertyName) =>
        ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));

    public System.Collections.IEnumerable GetErrors(string propertyName)
    {
        if (string.IsNullOrEmpty(propertyName)
            || !_validationErrors.ContainsKey(propertyName))
            return null;

        return _validationErrors[propertyName];
    }

    public bool HasErrors => _validationErrors.Count > 0;
    #endregion

}

Кстати, вы должны предпочесть INotifyDataErrorInfo над IDataErrorInfo, начиная с .NET Framework 4.5.

...