0
votes

I have a table in my database which has two columns:

HID: a hierarchyid

Name: a string

In my application I have a Node class that just has those two properties. I import the data into Node instantations and save them all with:

Dim Nodes As New List(Of Node)

I know that works because I've reviewed the data.

I have a wpf window that only has a Treeview on it. In my code behind I set the context of my window:

DataContext = Nodes

and now I want to populate the Treeview with this data. That is where I come up short. I have:

<Window.Resources>
    <HierarchicalDataTemplate
        x:Key="MyTemplate"
        ItemsSource="{Binding}">
        <TextBlock Text="{Binding Path=Name}" />
    </HierarchicalDataTemplate>
</Window.Resources>
<TreeView
    ItemsSource ="{Binding Path=Name}"
    ItemTemplate="{Binding Path=MyTemplate}">
</TreeView>

which does not work. Where am I going wrong?

EDIT1: I changed ItemsSource in the HierarchicalDataTemplate to:

ItemsSource="{Binding Path=HID}"

and set the ItemTemplate of the Treeview itself to:

ItemsSource ="{Binding}"

which seems intuitively right but creates errors saying HID is not a property of my Node class. Huh?

Edit2: Here is some sample data:

/ John  
/1/ Jim  
/2/ Mary  
/1/1/ Sam  
/1/1/1/ Nancy  
/2/1/ Sharon  
/2/1/1/ Joe  
/2/1/1/1/ Henry  
/2/1/1/1/ Ellen  
/2/1/1/1/1/ Bart  

================================
Edit 2
I have rewritten my processing of the data from the database so that the items in the tree have child items in the format necessary for the Treeview control. I have also changed my XAML to the following:

<Window.Resources>
    <HierarchicalDataTemplate
        x:Key="ChildTemplate">
        <TextBlock Text="{Binding Path=Name}" />
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate
        x:Key="ParentTemplate"
        ItemsSource="{Binding Path=ChildNodes}"
        ItemTemplate="{StaticResource ChildTemplate}">
        <TextBlock Text="{Binding Path=Name}" />
    </HierarchicalDataTemplate>
</Window.Resources>
<TreeView
    ItemsSource="{Binding}"
    ItemTemplate="{StaticResource ParentTemplate}">     
</TreeView>.

In my treeview I see the rootnode and only the first level below that. There are several levels below the first level that are not presented. What am I doing wrong?

======================
Edit 3:
I only have one class:

PersonID: Long
ParentID: Long
PersonName: String
Children: List (of Person)

I have traced the creation of all the items by watching them being created from my post processing of the data out of my database. The various instances of the classes are being populated correctly.

Using the data I originally posted, for example, John is one instance and he has two "children", Jim and Mary

=================================
Edit 4:
Forget the data from my database and all the code that I use to process the data. I stripped all that away and replaced it with the following procedure in which I just manually define 3 nodes:

Private Sub Window1_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
    Dim RootNode As New Node With {.ID = 1, .ParentID = 0, .Name = "Root"}
    Dim node2 As New Node With {.ID = 2, .ParentID = 1, .Name = "son1 of Root"}
    Dim node3 As New Node With {.ID = 3, .ParentID = 2, .Name = "son1 of son1"}
    node2.ChildNodes.Add(node3)   'Make node3 a child of node2
    RootNode.ChildNodes.Add(node2)   'Make node2 a child of the root node
    Nodes.Add(RootNode)   'Add the root node to the list of nodes
    DataContext = Nodes   'Make that list my data context
End Sub

I am using the definition of my Person class in Edit 3. Here I just define the Root Node and two other nodes. I add node3 as a child to node 2 then I add node 2 as a child to the root node and finally I add the root node to the Nodes List, which is then set as the datacontext for the Treeview. That's it.

Using the datatemplate shown in Edit 2, I should have this in my tree view:

Root
    son1 of Root
        son1 of son1

but I don't. Node 2 does not expand to show Node 3. In other words, I just see this:

Root
    son1 of Root

Needless to say, I have no idea what is wrong.

1
wpf-tutorial.com/treeview-control/… - if I remember correctly the type is very specific for binding.OneFineDay
I've already worked through those examples. They are not recursive which is exactly the stumbling block I can't get passed.SezMe

1 Answers

0
votes

You should bind the ItemsSource property of the TreeView to the List(Of Node). Try this:

<TreeView ItemsSource="{Binding}">
    <TreeView.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}" />
        </DataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

It should populate the TreeView with the root nodes.

For any hierarchical data to be displayed, you need to add a ChildNodes property to the Node class and populate this one of each node with the corresponding child nodes. Then it would make sense to use an HierarchicalDataTemplate:

<HierarchicalDataTemplate ItemsSource="{Binding ChildNodes}">
    <TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>

Edit:

This should work just fine:

Public Class Node
    Public Property Id As Integer
    Public Property Name As String
    Public Property ParentId As Integer
    Public Property ChildNodes As List(Of Node) = New List(Of Node)
End Class

Private Sub Window1_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
    Dim Nodes = New List(Of Node)
    Dim RootNode As New Node With {.Id = 1, .ParentId = 0, .Name = "Root"}
    Dim node2 As New Node With {.ID = 2, .ParentID = 1, .Name = "son1 of Root"}
    Dim node3 As New Node With {.ID = 3, .ParentID = 2, .Name = "son1 of son1"}
    node2.ChildNodes.Add(node3)   'Make node3 a child of node2
    RootNode.ChildNodes.Add(node2)   'Make node2 a child of the root node
    Nodes.Add(RootNode)   'Add the root node to the list of nodes
    DataContext = Nodes   'Make that list my data context
End Sub

<TreeView ItemsSource="{Binding}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding ChildNodes}">
            <TextBlock Text="{Binding Path=Name}" />
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

enter image description here