Implementing INotifyPropertyChanged: An Alternative Approach

,

Although there is nothing manifestly wrong with adding the OnPropertyChanged method to every class that implements INotifyPropertyChanged (apart from violating the DRY principle), it makes sense to extract the change notification code into a reusable class, because this allows you to not only reduce boilerplate code but also to add other features to the event-raising code, such as improving support for multithreaded apps and implementing INotifyPropertyChanging (as well as INotifyPropertyChanged).

The WPUnleashed project in the downloadable sample code includes such a class, named PropertyChangeNotifier. The ViewModelBase class delegates change notification to a PropertyChangeNotifier instance.

Throughout this book you frequently see viewmodel properties (with backing fields) resembling the following:

string foo;

public string Foo
{
    get
    {
        return foo;
    }
    set
    {
        Assign(ref foo, value);
    }
}

Here, the name of the property, the current value, and the new value are passed to the base class’s Assign method. The following excerpt shows the signature of the Assign method:

public AssignmentResult Assign<TField>(
        ref TField field,
        TField newValue,
        [CallerMemberName] string propertyName = "")
{
...
}

The Assign method updates the field value, while also offering the following advantages:

Image The application’s Dispatcher automatically raises the PropertyChanged event on the UI thread if called from a non-UI thread. This eliminates the need to add Dispatcher.BeginInvoke calls to a viewmodel to avoid cross-thread errors.

Image The Assign method also raises a PropertyChanging event. PropertyChangeNotifier implements INotifyPropertyChanging interface as well as INotifyPropertyChanged and allows a subscriber to cancel an update if desired.

Image PropertyChangeNotifier assists the viewmodel in remaining UI technology agnostic. That is, retrieving an application’s Dispatcher in a Windows Phone app is done differently in a WPF application.

Image PropertyChangeNotifier uses a weak reference to its owner, thereby preventing memory leaks from occurring when targets fail to unsubscribe from events.

Image The single line Assign method reduces the amount of boilerplate code in properties.

The return value of the Assign method is an AssignmentResult enum value, whose values are described in the following list:

Image SuccessThe assignment occurred and the field value now equals the new value.

Image CancelledA subscriber to the PropertyChanging event cancelled the assignment. This relies on a custom extension to the INotifyPropertyChanging event.

Image AlreadyAssignedNo assignment was made because the existing field value was already equal to the new value.

Image OwnerDisposedThe PropertyChangeNotifier uses a weak reference to the object for which it is providing property changing monitoring. This value indicates that no assignment was performed because the owner object has been disposed.

Because property change notification is such a common requirement of model and viewmodel classes, for the sake of convenience a NotifyPropertyChangeBase class is also provided in the downloadable sample code. It leverages an instance of the PropertyChangeNotifier, and can be used as a base class for any class that needs INotifyPropertyChanged to be implemented.

In particular, the ViewModelBase class inherits from this class (see Figure 2.10).

Image

FIGURE 2.10 ViewModelBase inherits from NotifyPropertyChangeBase, which has a PropertyChangeNotifier.

The implementation details of the PropertyChangeNotifier are lengthy and are not included in this section. However, you can find an article already covering the topic at http://danielvaughan.org/post/Property-Change-Notification-using-a-Weak-Referencing-Strategy.aspx.

Before moving on to commanding, be assured that you do not need to use the property notification system presented here in your own projects. If you are happy using the traditional approach to INPC, that is perfectly fine. Be mindful, however, that a lot of the phone SDK APIs have events that do not always return on the UI thread, and you may need to rely more heavily on the Dispatcher to prevent cross-thread errors.

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

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