Question

I have WPF form with regular controls: combobox, TextEdit etc.

I am using standard WPF validation:

  1. ViewModel mandatory properties have required attribute w/ message
  2. ViewModel implements IDataErrorInfo
  3. Mandatory Control has ValidatesOnDataErrors=True, NotifyOnValidationError=True in binding

When form is shown with new ViewModel mandatory controls are adorned w/ Error template. To me it seems that it is how WPF validation suppose and designed to work.

Other people on my team argue (respectfully) that it is not acceptable practice to show user validation errors before user entered any data.

Which makes sense to me. So if I want to show validation error only after user entered data I need somehow suspend validation until user enters data and then trigger validation. To me it seems like reinventing a wheel.

Was it helpful?

Solution

There is a really simple way to 'ignore' the validation of the IDataErrorInfo interface. Now different developers will implement their validation in different ways, but at some stage and in some location, we will all have some if ... else statements. This solution will require you to add a bool property to your data type class(es), or preferably a base class for your data types, if you have one:

public bool IsValidatable { get; set; } // Implement INotifyPropertyChanged here

Of course, you'll need to notify the INotifyPropertyChanged.PropertyChanged event of changes to this property, so please don't follow my lazy example above. Now, you may well have guessed the rest of the solution... it just involves an additional if statement wherever you have defined your validation conditons:

public override string this[string propertyName]
{
    get
    {
        string error = string.Empty;
        if (IsValidatable)
        { 
            if (propertyName == "Name" && Name.IsNullOrEmpty()) error = "You must enter the Name field.";
            else if (propertyName == "Name" && !Name.ValidateMaximumLength(127)) error = propertyName.GetMaximumLengthError(127);
            ...
            else if (propertyName == "Description" && !Description.ValidateMaximumLength(512)) error = propertyName.GetMaximumLengthError(512);
        }
        return error;
    }
}

Finally, to make your data type validatable, simply do this from your view model:

dataType.IsValidatable = true;

To stop validation, simply do this from your view model:

dataType.IsValidatable = false;

This is easily extendable... if you have defined a custom collection for your data types, you can simply iterate through each collection item and set the IsValidatable property to the input value:

collection.IsValidatable = true;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top