Binding Silverlight treeview control - MVVM

Binding Silverlight treeview control - MVVM

Old forum URL: forums.lhotka.net/forums/t/8638.aspx


Larry posted on Wednesday, March 10, 2010

There have been several earlier posts regarding binding BOs to treeview controls in Windows Forms and Web forms but we are trying to bind to Silverlight treeview using MVVM with a Csla based tree structure that is retrieved from the db. Because the number of levels of the tree (and the tree nodes) is variable depending on the criteria for the query we would like to have the implementation be somewhat generic. That is, the number of levels and the number of tree nodes at each levels is determined at runtime.

An example of a generic tree implementation for Silverlight can be found on Justin Angel's blog at
(http://blogs.silverlight.net/blogs/justinangel/archive/2008/11/18/silverlight-toolkit-treeview-treeviewitem-amp-hierarchaldatatemplate.aspx). It is a rather long article but about midway he describes a simple treecontrol that uses the XAML "HierarchicalDataTemplate" and he binds the tree to a list (at page load) that populates the tree control - it works nicely. Has anyone done a similar implementation using SL/MVVM with Csla?

We tried populating a hierarchical structure with BusinessListBase -> BusinessBase and enabled the tree control to bind to the Model but it only displays the first level of the tree. Any property of the first level can be bound and displayed but we couldn't get the second level to display even though we can verify that the root object does have populated children/grandchildren nodes.

Larry

RockfordLhotka replied on Wednesday, March 10, 2010

CSLA supports a tree structure where a node can have a list of other nodes:

node -> nodelist -> node(s)

I haven't looked into this myself, but does the treeview want a list of lists structure:

list -> list -> list

where every node is a node and is a list?

If so, you'd need to use viewmodel concepts to reshape the object model, merging each BusinessBase and its associated BusinessListBase into a single object.

skagen00 replied on Thursday, March 11, 2010

I actually just finished with some work in this kind of area where I had an arbitrarily depthed tree of objects - but objects where I wanted to show multiple columns of data for (formatted amounts, etc).

So a tree view just didn't look like the best option for me.

I ended up populating the business object in a manner such that I loaded it in the proper "hierarchical order" and then exposed a method that would run through an efficient algorithm (on the client side) to establish non-serialized references between items in the list - one pointing to the parent and one a collection of the item's children - it also established a non-serialized depth property.

Then, I bound the list to a grid, and used a converter to bind the margin of the first column (which contained an expand/collapse sort of button) to a multiple of the depth. Since I had a handle on children of each item, it was easy to respond to the expand/contract to hide/show the appropriate items in the view for the grid.

I am guessing that this as far as you're taking your treeview but I figured searches looking to do this sort of thing will stumble upon this post so I figured I'd share.

Larry replied on Friday, March 12, 2010

Thanks Rocky and Skagen00 for your replies.

After a fair amount of investigation we were able to get the treeview control to work the way we hoped. It is handling trees with arbitrary depths as skagen00 mentioned and as described in Justin Angel's article. Although we are using a small bit of code behind in addition to the viewmodel, we hope to eventually be able to refactor that out.

We needed to the small bit of code behind to handle sending several commands to the VM, and navigation to another page - the things I  know you are working on Rocky. The business object(s) structure that is working has a root TreeNodelist(BusinessListBase) with sub TreeNode(BusinessBase). Each TreeNode Business Object has a TreeNodeList property to extend the sub levels of the hierarchical tree.


By next week a colleague will post more details to share.

Ranjini replied on Friday, March 12, 2010

I work with Larry and after much persistence and playing around with the MVVM Test Project (thanks to Rocky), we found a way to make it work for us conforming for the most part to the CSLA + MVVM structure. Our layout required that the tree be loaded on a button click event and since there was also the need to navigate a frame within the user control to a different page on the same click event, we had to make use of some code behind.

There were 2 key parts to this. The first part was trying to figure out what hierarchical structure was acceptable to the tree control and Justin Angel’s blog (http://blogs.silverlight.net/blogs/justinangel/archive/2008/11/18/silverlight-toolkit-treeview-treeviewitem-amp-hierarchaldatatemplate.aspx) helped us there.  The second was to figure out the binding associated with the control itself and the hierarchical data template. Following is the XAML snippet we ended up with eventually. TreeListViewModel is the view model object we are using to bind the treeview.

XAML Code:

                <UserControl.Resources>

                      <this:TreeListViewModel x:Key="TreeListModel" />

<common:HierarchicalDataTemplate x:Key="TreeTemplate"  ItemsSource="{Binding Path=TreeNodeList}">

                  <StackPanel Orientation="Horizontal">

                        <TextBlock Text="{Binding Name}" />

                  </StackPanel>

        </common:HierarchicalDataTemplate>

      </UserControl.Resources>

 

      <controls:TreeView x:Name="treeViewCtrl"

      DataContext="{StaticResource TreeListModel}" ItemsSource="{Binding Path=Model}"                          

      ItemTemplate="{StaticResource TreeTemplate}" />

 At run time, here is the TreeListModel Structure. This should give a good idea about the binding BO. The Model itself is of type TreeNodeList (BLB) which contains children TreeNodes (BB) which in turn contains Name property, Level Property, SearchExpression Property and children TreeNodeLists.

 

I can definitely see how this can be confusing but after much trial and error this worked. I am also attaching all the objects and code associated with buiding the tree to this post along with a snapshot of the TreeListModel structure at runtime (so you can see how the hierarchical data is organized). Hope it helps someone and saves them some aggravation!

 Thanks

Ranjini

 

 

 

 

 

     

 

     

Ranjini replied on Friday, March 12, 2010

I work with Larry and after much persistence and playing around with the MVVM Test Project (thanks to Rocky), we found a way to make it work for us conforming for the most part to the CSLA + MVVM structure. Our layout required that the tree be loaded on a button click event and since there was also the need to navigate a frame within the user control to a different page on the same click event, we had to make use of some code behind.

There were 2 key parts to this. The first part was trying to figure out what hierarchical structure was acceptable to the tree control and Justin Angel’s blog (http://blogs.silverlight.net/blogs/justinangel/archive/2008/11/18/silverlight-toolkit-treeview-treeviewitem-amp-hierarchaldatatemplate.aspx) helped us there.  The second was to figure out the binding associated with the control itself and the hierarchical data template. Following is the XAML snippet we ended up with eventually. TreeListViewModel is the view model object we are using to bind the treeview.

XAML Code:

                <UserControl.Resources>

                      <this:TreeListViewModel x:Key="TreeListModel" />

<common:HierarchicalDataTemplate x:Key="TreeTemplate"  ItemsSource="{Binding Path=TreeNodeList}">

                  <StackPanel Orientation="Horizontal">

                        <TextBlock Text="{Binding Name}" />

                  </StackPanel>

        </common:HierarchicalDataTemplate>

      </UserControl.Resources>

 

      <controls:TreeView x:Name="treeViewCtrl"

      DataContext="{StaticResource TreeListModel}" ItemsSource="{Binding Path=Model}"                          

      ItemTemplate="{StaticResource TreeTemplate}" />

 At run time, here is the TreeListModel Structure. This should give a good idea about the binding BO. The Model itself is of type TreeNodeList (BLB) which contains children TreeNodes (BB) which in turn contains Name property, Level Property, SearchExpression Property and children TreeNodeLists.

 

I can definitely see how this can be confusing but after much trial and error this worked. I am also attaching all the objects and code associated with buiding the tree to this post along with a snapshot of the TreeListModel structure at runtime (so you can see how the hierarchical data is organized). Hope it helps someone and saves them some aggravation!

 Thanks

Ranjini

 

 

 

 

 

     

 

     

Ranjini replied on Friday, March 12, 2010

I work with Larry and after much persistence and playing around with the MVVM Test Project (thanks to Rocky), we found a way to make it work for us conforming for the most part to the CSLA + MVVM structure. Our layout required that the tree be loaded on a button click event and since there was also the need to navigate a frame within the user control to a different page on the same click event, we had to make use of some code behind.

There were 2 key parts to this. The first part was trying to figure out what hierarchical structure was acceptable to the tree control and Justin Angel’s blog (http://blogs.silverlight.net/blogs/justinangel/archive/2008/11/18/silverlight-toolkit-treeview-treeviewitem-amp-hierarchaldatatemplate.aspx) helped us there.  The second was to figure out the binding associated with the control itself and the hierarchical data template. Following is the XAML snippet we ended up with eventually. TreeListViewModel is the view model object we are using to bind the treeview.

XAML Code:

                <UserControl.Resources>

                      <this:TreeListViewModel x:Key="TreeListModel" />

<common:HierarchicalDataTemplate x:Key="TreeTemplate"  ItemsSource="{Binding Path=TreeNodeList}">

                  <StackPanel Orientation="Horizontal">

                        <TextBlock Text="{Binding Name}" />

                  </StackPanel>

        </common:HierarchicalDataTemplate>

      </UserControl.Resources>

 

      <controls:TreeView x:Name="treeViewCtrl"

      DataContext="{StaticResource TreeListModel}" ItemsSource="{Binding Path=Model}"                          

      ItemTemplate="{StaticResource TreeTemplate}" />

 At run time, here is the TreeListModel Structure. This should give a good idea about the binding BO. The Model itself is of type TreeNodeList (BLB) which contains children TreeNodes (BB) which in turn contains Name property, Level Property, SearchExpression Property and children TreeNodeLists.

 

I can definitely see how this can be confusing but after much trial and error this worked. I am also attaching all the objects and code associated with buiding the tree to this post along with a snapshot of the TreeListModel structure at runtime (so you can see how the hierarchical data is organized). Hope it helps someone and saves them some aggravation!

 Thanks

Ranjini

 

 

 

 

 

     

 

     

simon replied on Monday, May 30, 2011

I go through the codes, it's a switchable objects!  Why did you split it four class?

Copyright (c) Marimer LLC