Monday, January 18, 2010

Using an Observable Object to share data between ViewModels

A good option for sharing data between ViewModels in Prism is to implement a simple Observer pattern. The Observable Object has a registered instance inside Unity and can be exposed to any ViewModel that needs to read/write to the shared data it holds.

The Observable implementation I describe below can really be thought of as a purpose-built, shared ViewModel. So why not call it a ViewModel? Simply because of one important difference - the Observable Object has no View. Furthermore, the name Observable implies that the class will be shared among any number of interested parties, rather than being tied to a View.

Step 1. Defining the Observable class

The class must implement INotifyPropertyChanged. E.g.:

public class SelectedContactObservable : INotifyPropertyChanged,
ISelectedContactObservable
{
...
}


Step 2. Configuring Unity

Unity is configured to use the class, then a single instance is registered so that it may be shared among all consumers.

_container.RegisterType(typeof(ISelectedContactObservable),
typeof(SelectedContactObservable));
_container.RegisterInstance(_container.Resolve<ISelectedContactObservable>());

Step 3. Use the Observable Object in your ViewModels

Use the Observable Object in any number of consumer classes (ViewModels) using constuctor injection.

public class ContactListViewModel : INotifyPropertyChanged
{
public ContactListViewModel(ISelectedContactObservable
selectedContactObservable)
{
...
}

public ISelectedContactObservable SelectedContactObservable
{
...
}
}

Step 4. Databind to the Observable Object in your Views

<TextBlock Text="{Binding SelectedContactObservable.SelectedContact.LastName}" />
<TextBlock Text="{Binding SelectedContactObservable.SelectedContact.FirstName}" />

Note that the actual observable object itself is exposed as a property on the ViewModel (rather than having some or all of its properties wrapped inside the ViewModel). This allows the change notifications to work with the databinding without the need of any additional code.

UPDATE: I have further worked this scenario to support dependent/calculated properties in this post.

No comments:

Post a Comment