Click here to Skip to main content
15,885,032 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
(VB.Net, WinForm) I am not having much success in populating a TreeView three levels deep. I've tried different code from various sources but those I tried got me nowhere.

I am retrieving my Nodes from a database. The table looks like this:
catID | catName | catParent | catImage

For all Root Nodes the "catParent" will contain no data. For all other Nodes the catParent will contain the Parent Node it belongs to. Do not confuse Parent node with Root node.

I first tried the following code (found almost everywhere, even here on CodeProject). I thought to use the .Find option as it meant that I just had to search for the Name of my Parent Node since Indexes aren't unique.

VB
Private Sub PopulateDocumentCategories()
        'Clear the Treeview
        tvDocuments.Nodes.Clear()
        'Get all the categories from the DB
        clReadFromDB.GetDocCategories()
        'Read through the datatable
        For i = 0 To clReadFromDB.catData.Rows.Count - 1
            'Test to see if category has a Parent Node
            If clReadFromDB.catData.Rows(i).Item(2) = "" Then
                'Category is a Parent Node
                tvDocuments.Nodes.Add(New System.Windows.Forms.TreeNode(clReadFromDB.catData.Rows(i).Item(1), _
                                                                        clReadFromDB.catData.Rows(i).Item(3), _
                                                                        clReadFromDB.catData.Rows(i).Item(3)))
            Else
                'Entry has a Parent node. Need to find the Parent node in the TreeView then add the Child node
                Try
                    Dim tn As TreeNode() = tvDocuments.Nodes(0).Nodes.Find(clReadFromDB.catData.Rows(i).Item(2).ToString, True)
                    For j As Integer = 0 To tn.Length - 1
                        tvDocuments.SelectedNode = tn(j)
                        tvDocuments.Nodes.Add(New System.Windows.Forms.TreeNode(clReadFromDB.catData.Rows(i).Item(1), _
                                                                        clReadFromDB.catData.Rows(i).Item(3), _
                                                                        clReadFromDB.catData.Rows(i).Item(3)))
                    Next
                Catch
                End Try
        Next i 'Datatable rows
        tvDocuments.ExpandAll()
    End Sub


This only adds the Root Nodes to the TreeView control and ignores all other nodes.

Went back to the drawing board and came up with the following code which actually populates the TreeView with the Root Nodes (Tier 1) and first level Child Nodes (Tier 2 Parent Nodes). However it does not add the last level of nodes (Tier 3).

VB
Private Sub PopulateDocumentCategories()
        'Clear the Treeview
        tvDocuments.Nodes.Clear()
        'Get all the categories from the DB
        clReadFromDB.GetDocCategories()
        'Read through the datatable
        For i = 0 To clReadFromDB.catData.Rows.Count - 1
            'Test to see if category has a Parent Node
            If clReadFromDB.catData.Rows(i).Item(2) = "" Then
                'Category is a Root Node
                tvDocuments.Nodes.Add(New System.Windows.Forms.TreeNode(clReadFromDB.catData.Rows(i).Item(1), _
                                                                        clReadFromDB.catData.Rows(i).Item(3), _
                                                                        clReadFromDB.catData.Rows(i).Item(3)))
            Else
                'Entry has a Parent node. Need to find the Parent node in the TreeView then add the Child node
                For Each node As TreeNode In tvDocuments.Nodes
                    'Find the Parent Node
                    If node.Text = clReadFromDB.catData.Rows(i).Item(2) Then
                        'Select the found Node
                        tvDocuments.SelectedNode = node
                        'Add the Child Node to the Selected Node
                        tvDocuments.SelectedNode.Nodes.Add(New System.Windows.Forms.TreeNode(clReadFromDB.catData.Rows(i).Item(1), _
                                                                                             clReadFromDB.catData.Rows(i).Item(3), _
                                                                                             clReadFromDB.catData.Rows(i).Item(3)))
                    End If
                Next node 'Treeview nodes
            End If
        Next i 'Datatable rows
        tvDocuments.ExpandAll()
    End Sub


Is there something that I am doing wrong or not considering while populating the TreeView programmatically ?
Posted
Updated 14-Sep-14 12:33pm
v2
Comments
Sergey Alexandrovich Kryukov 14-Sep-14 19:15pm    
I have an impression that the only thing you need is a little more attention for the obvious.
I posted an answer in Solution 1, but probably just my comment above would be enough. :-)
—SA

I see no need in digging into this code deep for the trivial algorithm of the TreeView population. It's enough to look at all your Add calls. It's always tvDocuments.Nodes.Add. If you are adding sub-nodes only to the nodes of only one object tvDocuments, why would having only the next-level nodes surprise you? Who is going to add sub-nodes for all other nodes?

No matter what you do, eventually you should use the property System.Windows.Forms.TreeNode.Nodes to add more nodes. And you never do it. Please see:
http://msdn.microsoft.com/en-us/library/system.windows.forms.treenode.nodes%28v=vs.110%29.aspx[^].

—SA
 
Share this answer
 
Comments
Tino Fourie 14-Sep-14 19:39pm    
Hey SA. Thanks for the reply. I looked into the System.Windows.Forms.TreeNode.Nodes as well as the MSDN link. However, VS2010 gives me this "Error 1 Type 'System.Windows.Forms.TreeNode.Nodes' is not defined."

The link you provided uses pre-selected nodes to move from one TreeView to another TreeView.

I have stepped into my code and from what I can gather is that my routine for some reason only reads the Root Nodes although TreeView.Nodes is supposed to return "all" the Nodes in the TreeView control. Why would that be? Is it perhaps the method I use to iterate through the TreeView.Nodes ?

Furthermore, I have also checked to see if it ever reads through the "Tier 2" nodes and from what I can see, it does not do that. Now the question still remains, am I iterating through the Nodes incorrectly or am I still adding the Nodes incorrectly ?
Sergey Alexandrovich Kryukov 14-Sep-14 21:24pm    
Well, and what make you thinking that this type might exist? :-)

This is not a type, this is the instance property. Don't use it as a type, use it as a property.
After all, I gave you a reference to documentation which explains it all. Just pay proper attention for this piece of documentation, instead of mechanically using System.Windows.Forms.TreeNode.Nodes.

—SA
Tino Fourie 14-Sep-14 20:51pm    
FYI: It was not how I added the nodes but actually how I read through the Nodes.
This might help you: http://msdn.microsoft.com/en-us/library/wwc698z7(v=vs.100).aspx[^]

SA, if you don't mind, could you provide me the code to do it the way you suggested please. I would like to have a look at both solutions... mine I know works perfect. I would like to broaden my knowledge if there is something extra to learn from it.
VB
'Populate Document Categories
 Private Sub PopulateDocumentCategories()
     'Clear the Treeview
     tvDocuments.Nodes.Clear()
     'Get all the categories from the DB
     clReadFromDB.GetDocCategories()
     'Read through the datatable
     For i = 0 To clReadFromDB.catData.Rows.Count - 1
         'Test to see if category has a Parent Node
         If clReadFromDB.catData.Rows(i).Item(2) = "" Then
             'Category is a Root Node
             tvDocuments.Nodes.Add(New System.Windows.Forms.TreeNode(clReadFromDB.catData.Rows(i).Item(1), _
                                                                     clReadFromDB.catData.Rows(i).Item(3), _
                                                                     clReadFromDB.catData.Rows(i).Item(3)))
         Else

             'Entry has a Parent node. Need to find the Parent node in the TreeView then add the Child node
             For Each ParentNode As TreeNode In tvDocuments.Nodes
                 If ParentNode.Text.ToString = clReadFromDB.catData.Rows(i).Item(2).ToString Then
                     'Select the found Node
                     tvDocuments.SelectedNode = ParentNode
                     'Add the Child Node to the Selected Node
                     tvDocuments.SelectedNode.Nodes.Add(New System.Windows.Forms.TreeNode(clReadFromDB.catData.Rows(i).Item(1), _
                                                                                          clReadFromDB.catData.Rows(i).Item(3), _
                                                                                          clReadFromDB.catData.Rows(i).Item(3)))
                     tvDocuments.Update()

                 Else
                     'Find the Child Node
                     For Each ChildNode As TreeNode In ParentNode.Nodes
                         If ChildNode.Text.ToString = clReadFromDB.catData.Rows(i).Item(2).ToString Then
                             'Select the found Node
                             tvDocuments.SelectedNode = ChildNode
                             'Add the Child Node to the Selected Node
                             tvDocuments.SelectedNode.Nodes.Add(New System.Windows.Forms.TreeNode(clReadFromDB.catData.Rows(i).Item(1), _
                                                                                                  clReadFromDB.catData.Rows(i).Item(3), _
                                                                                                  clReadFromDB.catData.Rows(i).Item(3)))
                             tvDocuments.Update()
                         End If

                     Next ChildNode

                 End If

             Next ParentNode 'Treeview nodes
         End If
     Next i 'Datatable rows
     tvDocuments.ExpandAll()
 End Sub


For more detailed information on the topic here is the MSDN link relating to Recursive Iteration:
http://msdn.microsoft.com/en-us/library/wwc698z7(v=vs.100).aspx[^]
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 14-Sep-14 21:25pm    
Is it really a solution? If it is not, what does it mean?
—SA
Tino Fourie 14-Sep-14 21:51pm    
Is it really a solution?

SA, I am truly sorry if my code is too complex for you to understand. Yes, I am guilty for not "copy & paste" the MSDN code into my code in order for you to follow what is actually happening. Before you post nonsense like this, why don't you try the code yourself THEN ONLY reply with your arrogant attitude. In fact I am still waiting for your code snippet from Solution 1 to be posted since you are so adamant that only your solution is the true solution.

Mind you, it is 4am here where I am, at this moment in time I do not have the energy to deal with your attitude. If you find anything wrong in my code then post the mistakes else just move along.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900