0

I'm not a experience vb.net programmer so I'm struggling with some code related to treeview node implementation:

My goal is to implement a hierarchical and editable structure related to a "Bill of Materials" (e.g. a house has a foundation, walls, roof,.. and walls has stones, plaster,....) The number of levels of this hierarchical structure is (per definition) unknown.

I'm able to populate a treeview(1) with SQL data to multiple but a fixed number of levels. The code I've implemented:

TreeView1.Nodes.Add(var01, var01).Nodes.Add(var02, var02) (example 2 levels)

where var01 and var02 the names within the structure are (e.g. House-Wall). The Node structure is build using a "for - next loop"

Officious by adding ".Nodes.Add(varXX, varXX)" I'm able to extend the level of the structure. My goal however is to implement "the adding of .Nodes.Add(varXX, varXX)" through a loop make the number of hierarchical levels flexible.

I tried to convert Treeview1.Nodes... to a string and build a (overall) string through a loop. Then I tried to convert this string to the treeview control. This principle doesn't unfortunately work.

Any advice would be appreciated.

mortb
  • 9,361
  • 3
  • 26
  • 44
Nicolaas
  • 1
  • 1
  • This is probably not exactly what you are doing, but you may use it as an example of a technique to use: https://www.aspsnippets.com/Articles/Bind-and-display-hierarchical-data-with-TreeView-in-ASPNet-using-C-and-VBNet.aspx – mortb Mar 02 '20 at 09:55
  • Does this answer your question? [Windows Forms VB.NET - Populate TreeView with Hierarchical data](https://stackoverflow.com/questions/2206417/windows-forms-vb-net-populate-treeview-with-hierarchical-data) – mortb Mar 02 '20 at 09:56

1 Answers1

0

Try something like this:

 Public Function GetBOMTree() As TreeNode
      Dim BOMTable As DataTable

      ' Assuming your hierarchy is small enough to do a full table load into BOMTable, put your SQL statements here

      Dim BOMDictionary = BOMTable.Rows.Cast(Of DataRow) _ ' Assumed to be a data table 
             .Where(Function(F) F.Item("ParentKey").GetType IsNot GetType(DBNull)) _
             .GroupBy(Function(F) CInt(F.Item("ParentKey"))) _ ' Assuming integer keys 
             .ToDictionary(Function(F) F.Key)

      Dim Root = BOMTable.Rows.Cast(Of DataRow) _
           .Where(Function(F) F.Item("ParentKey").GetType Is GetType(DBNull)) _
           .FirstOrDefault

      If Root IsNot Nothing Then

         Dim GetTree As Func(Of DataRow, TreeNode) = ' The "as Func" is necessary to allow recursion
               Function(D As DataRow) As TreeNode
                  Dim Result As New TreeNode
                  Dim Key = CInt(D.Item("PrimaryKey"))

                  Result.Tag = Key 
                  Result.Text = CStr(D.Item("Description"))

                  If BOMDictionary.ContainsKey(Key) Then 
                     Dim Children = BOMDictionary.Item(Key)
                     For Each Child In Children.OrderBy(function(F) cstr(f.item("Description")))
                        Result.Nodes.Add(GetTree(Child))
                     Next
                  End If
                  Return Result

               End Function

         Return GetTree(Root)
      Else
         Return Nothing
      End If



   End Function

The way this works is using a little recursion, and some LINQ to objects to get an initial dictionary. I've made the assumption that your hierarchy is in you table and not an external table, but if it's external, you can modify what you see here to make it work. I've assumed integer keys. Code is trivial to modify if you are using GUID's, just cast appropriately.

Robert Richter
  • 278
  • 2
  • 9