Home > Back-end >  How to get a list of all errors in a column on a WPF DataGrid control?
How to get a list of all errors in a column on a WPF DataGrid control?

Time:03-08

I have a DataGrid control bound to an ObservableCollection of a model type that implements INotifyDataErrorInfo. The DataGrid displays the error info correctly on cells in the PhoneNumber column. However, I want to display the number of phone numbers with error to the user before they submit the data to the database (say, a number with a tooltip somewhere on the page). I've scoured the internet for any clue about this, but nothing. Here's the implementation of the model class:

''' 
public class ContactModel : ObservableObject, INotifyDataErrorInfo
{
    private readonly List<string> _errors = new();

    private string _firstName = String.Empty;
    public string FirstName
    {
        get => _firstName;
        set
        {
            _firstName = value;
            OnPropertyChanged(nameof(FirstName));
        }
    }

    private string _lastName = String.Empty;
    public string LastName
    {
        get => _lastName;
        set
        {
            _lastName = value;
            OnPropertyChanged(nameof(LastName));
        }
    }

    private string _phoneNumber = string.Empty;
    public string PhoneNumber
    {
        get => _phoneNumber;
        set
        {
            _phoneNumber = value;
            OnPropertyChanged(nameof(PhoneNumber));
        }
    }

    public bool HasErrors
    {
        get
        {
            return _errors.Any();
        }
    }

    public IEnumerable GetErrors(string? propertyName)
    {
        switch (propertyName)
        {
            case nameof(PhoneNumber):
                if (string.IsNullOrEmpty(nameof(PhoneNumber))
                {
                    _errors.Add("Phone number is blank");
                }
                break;

            case nameof(FirstName):
                // do nothing
                break;

            case nameof(LastName):
                // do nothing
                break;

            default:
                break;
        }

        return _errors;
    }

    public event EventHandler<DataErrorsChangedEventArgs>? ErrorsChanged;
}

'''

CodePudding user response:

this is a missunderstanding on INotifyDataErrorInfo implementation on this way

  1. you can validate only one property. if two property have errors, you cannot find error of each property
  2. you cannot find model is valid or not, until GetError called.

add ValidationErrors property

make "_errors" property as public property as ObservableCollection

private ObservableCollection<ValidationResult> _errors;
public ObservableCollection<ValidationResult> Errors
{
   get{return _errors;}
   set{_errors = value;
       OnPropertyChanged(nameof(Errors));
       }
}

then construct it at model cunstructor.

then invoke validation procedure on property setter.

    private string _phoneNumber = string.Empty;
        public string PhoneNumber
        {
            get => _phoneNumber;
            set
            {
                 _errors.RemoveRange(_errors.Where(w=> w.Membernames.Containes(nameof(PhoneNumber))));
                _phoneNumber = value;
                if (string.IsNullOrEmpty(value)
                {
                    _errors.Add(new ValidationResult("Phone number is blank",new string[]{nameof(PhoneNumber)}));
ErrorsChanged?.invoke(this,new DataErrorsChangedEventArgs(nameof(PhoneNumber)));
                }
                OnPropertyChanged(nameof(PhoneNumber));
            }
        }

change GetError to

 public IEnumerable GetErrors(string? propertyName)
    {
         return _errors.Where(w=> w.Membernames.Containes(propertyName);
    }

so you can add a listbox (or a complex control called ValidationSummary) to your form and bind it's source to ValidationErrors property of your model.

best practice implementation of InotifyPropertyInfo is to Implement it on basemodel (ObservableObject in your sample) class.

  • Related