A Reusable Implementation of the NotifyDataErrorInfo Interface

,

The DataErrorNotifier class in the downloadable sample code is a reusable implementation of the INotifyDataErrorInfo interface.

DataErrorNotifier makes implementing asynchronous validation easy. With the addition of a single validation method to your viewmodel, DataErrorNotifier manages the list of errors and takes care of raising data error events. Furthermore, validation can be restricted by registering only those properties that you want to be validated.

DataErrorNotifier is designed to validate classes that implement a custom IValidateData interface, such as the ViewModelBase class. The validation logic has been decoupled from the ViewModelBase class to be reusable for other types as well.

The DataErrorNotifier requires an instance of IValidateData. The IValidateData interface defines an asynchronous validation mechanism with a nonblocking BeginValidate method and an event to signal when validation is complete (see Figure 26.11).

Image

FIGURE 26.11 DataErrorNotifier provides validation for the ViewModelBase class.

The ViewModelBase class implements IValidateData. ViewModelBase creates an instance of the DataErrorNotifier class and passes itself to the DataErrorNotifier’s constructor, as shown:

protected ViewModelBase()
{
    dataErrorNotifier = new DataErrorNotifier(this, this);
...
}

DataErrorNotifier subscribes to the viewmodel’s PropertyChanged event. When the PropertyChanged event is raised, validation is performed automatically.


Note

If you want validation to be performed prior to the setting of the property’s backing field, modify the DataErrorNotifier so that it subscribes to the PropertyChanging event of the viewmodel rather than its PropertyChanged event.


The DataErrorNotifier takes responsibility for the INotifyDataErrorInfo implementation. Ordinarily, a viewmodel calls only the ViewModelBase’s AddValidationProperty and IsComplete methods. Both the ViewModelBase class and the DataErrorNotifier implement INotifyDataErrorInfo. The ViewModelBase class, however, merely calls through to its DataErrorNotifier instance.

Leveraging the DataErrorNotifier Class

To register a property for validation in a viewmodel, the AddValidationProperty is called in the constructor of the viewmodel, as demonstrated in the following excerpt:

AddValidationProperty(() => ARequiredStringProperty);

AddValidationProperty causes the DataErrorNotifier to automatically attempt to validate the property when the property changes, or when the viewmodel is being validated in its entirety.

The lambda expression provides the ViewModelBase class with the means to resolve both the property and the name of the property. The ViewModelBase.AddValidationProperty method retrieves the name of the property and passes it and a Func to the DataErrorNotifier, as shown:

protected void AddValidationProperty(Expression<Func<object>> expression)
{
    PropertyInfo propertyInfo = PropertyUtility.GetPropertyInfo(expression);
    string name = propertyInfo.Name;
    Func<object> getter = (Func<object>)Delegate.CreateDelegate(
                                typeof(Func<object>),
                                this,
                                propertyInfo.GetGetMethod());

    dataErrorNotifier.AddValidationProperty(name, getter);
}

DataErrorNotifier stores the association between the property name and the Func, which allows the property to be retrieved by name during validation.

The AddValidationProperty method of the DataErrorNotifier is shown in the following excerpt:

public void AddValidationProperty(string name, Func<object> property)
{
    lock (propertyDictionaryLock)
    {
        propertyDictionary[name] = property;
    }
}

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.166.75