Treeview & Shared service

Topics: Prism v4 - WPF 4
Nov 28, 2011 at 7:12 PM

Hi,

 

I have several questions regarding the use of a TreeView with PRISM & MVVM.

 

I have several models that I want to put inside a treeview. They are all represented with a checkbox (checked property), an icon and a name. There are inheritance relations between some of them. Some of them are used as nodes in the treeview and other as leaves.

 

-          The first question is a general MVVM question: Do I have to create different TreeViewItemViewModels (one for each model)? Or should I create a generic TreeViewItemViewModel class that encapsulates all the models? Basically, the only changes between the ViewModels are the item icon (one for each model) and maybe the context menu. The first solution seems cleaner but it means that while creating the ObservableCollection, the correct ViewModel should be determined for each item depending on its model type. What is your opinion on this choice?

 

-          Secondly, I want to communicate with the other modules when an item gets disabled (i.e. his checkbox is unchecked). I was thinking of using a shared service for that purpose. The shared service is resolved with MEF using the ImportingConstructors attribute in the main treeview ViewModel. But to my mind, the items must have a direct access to this shared service in order to notify it when the Checked property is changed. Thus, the shared service instance is passed to the TreeViewItemViewModels when they are created. Is that correct?

 

I hope my explanation are not too messy,

Thanks for your help,

Best,

Developer
Nov 29, 2011 at 7:22 PM

Hi,

Regarding your first question about MVVM, take into account that this decision will be strictly related to your particular scenario. From my point of view, using ViewModels that inherit from a generic base ViewModel class could be a reasonable approach.

Second, to  achieve communication with other modules using Shared Services like you mentioned sounds like a good idea. Also, another approach could be using Event Aggregation.

You can find more information about these approaches in the Prism documentation at MSDN:

I hope you find this handy,

Agustin Adami
http://blogs.southworks.net/aadami


Nov 30, 2011 at 8:22 PM

Hi Augustin,

Tanks for your answer.

It helps me but I am still not very clear about all of this (MVVM, Prism, etc.)

In particular, I have another question regarding bindings and events. I have some data (instances of a model that implement INotifyPropertyChanged) that are shared with a shared service between different views (TreeView, etc.). Some of the views are directly binded to the models (through the associated ViewModel). Therefore, when one element is selected, the property IsSelected is set to true and it gets automatically selected in the other views with the binding. Howerver, in one of the views, the binding can’t be used (not WPF). What do I have to use in order to select the item in this view as well?

 - Listen for the PropertyChanged event for the shared data in order to update consequently when the “IsSelected” property is set to true?

-   Use event aggregator but it seems a bit weird to me as we have this PropertyChanged event...

Thanks again for your help,

Best,

Developer
Dec 1, 2011 at 3:59 PM

Hi,

The approach that should be used for your case depends mostly of your personal preferences and the requirements of your scenario.

Based on my understanding, subscribing to the PropertyChanged event seems like a valid approach. However, take into account that you might require to implement some custom logic to unsubscribe for this event when needed to avoid keeping the subscriber alive (for example, when the view / view model is no longer needed, it they are subscribed to the event, they will be kept alive until the subscription is undone), which is the advantage that the Event Aggregator provides.

I hope you find this useful,

Damian Cherubini
http://blogs.southworks.net/dcherubini

Dec 1, 2011 at 4:53 PM

Thanks Damian,

That fits with my understanding.

Best,