Resolved Create a ViewModel for Treeview?

StoneCodeMonkey

Well-known member
Joined
Apr 17, 2009
Messages
56
Programming Experience
5-10
Hello all,

<rant>Treeview? Wow this thing is so different in WPF!</rant>

Ok, it started out simple enough in my mind, pop a Treeview onto the window and use code behind to add items as I need them. However, according to this article I am doing it all wrong.

According to the article I should be simplifying the Treeview by using a ViewModel pattern. I have no idea what that means, and the article has thoroughly confused me. Ok, maybe some idea of what it is saying. That the hierarchical data should be just that data, and that the Treeview, well, should be nothing more than a view of the data. Which is a far departure from what I did in Winforms. {I would store objects in the Tag of a node, gave me easy access to an item}

I also noticed that the Treeview can have a HierarchicalDataTemplate, which also confuses me.

This is what my Treeview looks like in a Winform app.
Capture.PNG

This XML explains which levels are added in code behind. In my new application, the top level will be "Servers", there will be at least one level below that called "Local" and possibly a 2nd that is called "Remote"

Items Local and Remote and all of their children will have to be added in code behind.

VB.NET:
            <TreeView>
                <TreeViewItem Header="Servers" FontWeight="Bold" FontSize="12">
                    <!--This item will be added via code behind-->
                    <TreeViewItem Header="Local" FontWeight="Bold" FontSize="12">
                        <!--This item will be added via code behind-->
                        <TreeViewItem Header="Data Access 2.XX" FontWeight="Bold" FontSize="12">
                            <!--These items will be added via code behind-->
                            <TreeViewItem Header="Graybox.Simulator" FontSize="10" Foreground="Blue"/>
                            <TreeViewItem Header="RSLinx OPC Server" FontSize="10" Foreground="Blue"/>
                            <TreeViewItem Header="RSLinx Remote OPC Server" FontSize="10" Foreground="Blue"/>
                            <TreeViewItem Header="Matrikon.OPC.Simulator" FontSize="10" Foreground="Blue">
                                <!--These items added on demand.-->
                                <TreeViewItem Header="Subscription 00" FontSize="10" Foreground="Red"/>
                                <TreeViewItem Header="Subscription 01" FontSize="10" Foreground="Red"/>
                            </TreeViewItem>
                        </TreeViewItem>
                        <!--These items will be added via code behind-->
                        <TreeViewItem Header="Data Access 3.00" FontWeight="Bold" FontSize="12">
                            <TreeViewItem Header="Graybox.Simulator" FontSize="10" Foreground="Blue"/>
                            <TreeViewItem Header="Matrikon.OPC.Simulator" FontSize="10" Foreground="Blue"/>
                        </TreeViewItem>
                    </TreeViewItem>
                </TreeViewItem>
            </TreeView>

I probably could achieve this similar to the Winform solution, but it wouldn't fit well in the WPF world of doing things. Obviously allot of other functionality in the application depends what item in the treeview has been selected.

If anyone is wondering, the tree represents OPC Servers that are installed locally or remotely that can be access by the client pc.
Each OPC server supports different features depending on which specification they are compliant to.
The application will use items from the tree that represent an available server to allow a connection to that server. The treeviewitem icon should update to show the "connected" status.
Once connected to a server subscriptions can be made. The server item on the tree lists all subscriptions it has.


How could I achieve this using HierarchicalDataTemplate or ViewModel pattern?

Regards
 
Last edited:
Ok, ViewModel is from MVVM. :)

From what I've read today, it would be the right way to go at this. Ya, I can say I have never read anything on MVVM. Living under a rock.

Still lots to read.
 
Well after spending the afternoon reading various articles on MVVM it started to make sense, as a method or pattern that is. I can certainly see the benefits of the patterns introduced by the concept.

For me however, it forced me to deal with binding in WPF. I'll probably catch allot of heat for saying this, but the real hero in the WPF - MVVM scenario is WPF.
The MVVM pattern is great, I think that it is similar to the process of building a Data Access Layer into your application. But with MVVM it is really about building a layer that plays very nice with the way WPF binding works.

And yes, after coming to that realization, I managed to create a ViewModel that supports the Treeview nicely.

For anyone that may not be familiar with ViewModel, it is simply a term used to describe your code behind that has been written explicitly to bind to the properties and such of WPF controls.

The real key for me was the realization that I could have an object (instantiated class) that has properties which can be bound to the Treeview, and that this object could be set as the DataContext of the Treeview.

For instance:

ViewModel is a class written with properties easily bound to properties on a Treeview.
VB.NET:
Dim vm As New ViewModel()

tv is just the Treeview on a Window
VB.NET:
tv.DataContext = vm


In the XML for the treeview, I bind the TreeView ItemSource to a property in the ViewModel class called Children which is a List(of T) property.
VB.NET:
        <TreeView Name="tv"
                  ItemsSource="{Binding Children}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                    <TextBlock Text="{Binding DisplayName}" />
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
Every child in the List(Of T) also has a property named DisplayName which gets bound to the Text of the treeview item and of course it's own List(Of T) children which gets bound to the HierarchicalData ItemSource.

Hope this helps everyone else.

Regards
 
Back
Top