TreeView node needs to inherit from ViewModelBase and TreeViewItem

Jun 2, 2011 at 6:41 PM

I am caught in the classic oop problem where my class needs to inherit from two base classes that I have no control over.

I have a TreeView control that has a hierarchy of my "BusinessUnit" classes.  This class has a property called "Subclasses" that is an ObservableCollection of BusinessUnits.  I'm using SimpleMVVM so that I need to notify property changes to the view from the view model.

I wanted to use the method "NotifyPropertyChanged" on the setter of the Subclasses property to ensure the TreeView knows when this changes.  To do this, I inherited BusinessUnit from ViewModelBase even though it is not the actual ViewModel for the View.  This actually worked very well and the TreeView receives the events when that property changes.

Unfortunately, I also need to control the tree from code.  I need to expand nodes and select node programmatically.  Even in Code Behind I can't seem to do this because my tree nodes do not derive from TreeViewItem.

So my problem is that I cannot inherit my BusinessUnit class from both ViewModelBase and TreeViewItem.

Does anyone have any suggestions?

Thanks,
Dogulas

Coordinator
Jun 2, 2011 at 7:06 PM
If you email me your project, I'll have a look: tony@tonysneed.com.
Tony
Jun 7, 2011 at 2:14 PM

Tony,

Have you had a chance to look at this yet?

Thanks,

Dogulas

Coordinator
Jun 7, 2011 at 4:41 PM

Hello Dogulas,

I finally got some time to research the topic of using the treeview with MVVM.  As you've discovered, the nature of the treeview makes using it with MVVM somewhat problematic.  My best advice at this point would be to refer you to an excellent article on the topic by Josh Smith.  It's targeted to WPF, but I believe it should also apply to Silverlight.

http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx

See if you can replicate what he's done there with the Simple MVVM Toolkit. I would suggest starting with the template that does not use RIA Services.  The main difference is that your model classes would inherit from ModelBase, which provides two-way data binding.  (With RIA Services, the entities have their own base class that provides data binding.)

Cheers,

Tony

Jun 8, 2011 at 1:29 PM

Tony,

Thanks for the reply.  I will check out this article and continue experimenting.  If I come up with a solution, I'll post it here.

One last thought before I go; in my current attempt, I inherit my base class from ViewModelBase so that I can call NotifyPropertyChanged from the objects that make up the nodes.  This prevents me from inheriting from TreeViewItem and accessing the tree functionality I need.

Well, the tree nodes aren't really the ViewModel.  There is a ViewModel that backs the view that the tres is in, I was just inheriting the node from ViewModelBase to get the notify functionality.  Is there any way to call NotifyPropertyChanged from the View's ViewModel via associated properties, thus freeing up my node to inherit from TreeViewItem?

Thanks,

Dogulas

Coordinator
Jun 8, 2011 at 5:12 PM

Hi Dogulas,

I have just put together a sample of using the Simple MVVM Toolkit with a Silverlight TreeView control bound to a hierarchical model.  There is no need to use TreeViewItem at all -- simply bind the treeview to a ViewModel property that exposes a hierarchical model.  Whatever treeview functionality you need should be handled as properties on either the parent ViewModel, or on the child ViewModel that represents each node.  In my sample I am using a class called Person for the model and just binding the hierarchical data template to the Children property of each Person.  You could just as easily wrap Person in a PersonViewModel that exposes properties such as IsExpanded or IsSelected (see Josh's sample for an example of doing that).

The NotifyPropertyChanged method is in the ViewModel base class, so you should get two-way data binding support there.  That event is fired in the property setters of the ViewModel, the code for which is generated when you use the mvvmprop code snippet.  The nature of events in general is that they can only be fired from within the class (or possibly an inherited class).

Here is the sample I created: http://tonysneed.com/download/SimpleMvvmTreeView.zip

I hope this helps you get started. And please let me know if you have any other questions.

Cheers,

Tony

Apr 18, 2012 at 7:19 AM

Interesting article tony.

Because I am newbie to WPF and MVVM, I have no idea how to replace the CreateFamilyTree in MockPersonServiceAgent.css with real database.

Could anyone give me a tip?

Thanks in advance,

Emino