mercredi 6 mai 2015

INotifyDataErrorInfo and binding exceptions

I'm using the INotifyDataErrorInfo interface to implement a general MVVM validation mechanism. I'm implementing the interface by calling OnValidate instead of OnPropertyChanged:

public void OnValidate(dynamic value, [CallerMemberName] string propertyName = null)
{
        if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        Validate(propertyName, value);
}

In the Validate Method I'm generating the validation errors, add them to a Dictionary and raise the ErrorsChanged event if a validation error was found or cleared:

if (entry.Validate(strValue, out errorNumber, out errorString) == false)
{
      _validationErrors[propertyName] = new List<string> {errorString};
      RaiseErrorsChanged(propertyName);
}
else if (_validationErrors.ContainsKey(propertyName))
{
      _validationErrors.Remove(propertyName);
      RaiseErrorsChanged(propertyName);
}

The HasErrors property is implemented by looking at the errors dictionary:

    public bool HasErrors
    {
         get { return _validationErrors.Any(kv => kv.Value != null 
                   && kv.Value.Count > 0); }
    }

To prevent the save button from being enabled when there is a validation error - The save command canExecuteMethod looks at the HasErrors property:

private bool IsSaveEnabled()
{
    return HasErrors == false;
}

Everything works fine except the case where I'm having binding errors - if the binded value is (for example) an integer a non integer is entered - the textbox's ErrorContent is updated with an error string: "Value 'something' could not be converted". But the INotifyDataErrorInfo mechanism is not updated about this. The HasErrors remains false and Save is enabled although there is an error in the view. I would like to find a way to propagate the binding exception to the INotifyDataErrorInfo mechanism so I would be able to:

  1. Disable the Save button (must).
  2. Change the validation error message to a more meaningful error string (nice to have).

I would like to find a general MVVM solution without adding code behind in the view.

Thank you for the help

Aucun commentaire:

Enregistrer un commentaire