Generate TreeView Control Dynamically from Query (VB.NET)

匆匆过客 提交于 2020-01-14 04:33:43

问题


I have never used TreeViews in the past and I want to display a hierarchical structure (recursive relationship of n levels). The data (available in a dataset - retrieved from database query) is in the following structure:

__ID__  | __NAME__  | __PARENT__ 
 1      | Patrick   |       
 2      | Mark      |
 3      | Scott     | 2
 4      | Jason     | 
 5      | Julian    |
 6      | John      | 6
 7      | Steve     |
 8      | George    | 1 
 9      | Robert    | 1
 10     | Rodney    | 8

I'm trying to produce the following output

- Patrick [1]
  - George [8]
    - Rodney [10]
  - Robert [9]

- Mark [2]
  - Scott [3]

- Julian [5]
  - John [6]

- Jason [4]

- Steve [7]

I'm trying to generate the Treeview control but have no experience with Treeviews. Any feedback or examples on how to achieve this would be really appreciated.


回答1:


To fill the TreeView from a DataTable, try the following code

Dim DataTable1 As New DataTable

Private Sub FillTestTable()
    DataTable1.Columns.Add("ID", GetType(Integer))
    DataTable1.Columns.Add("NAME", GetType(String))
    DataTable1.Columns.Add("PARENT", GetType(Integer))
    DataTable1.Columns.Add("LEVEL", GetType(Integer))

    DataTable1.Rows.Add(1, "Patrick")
    DataTable1.Rows.Add(2, "Mark")
    DataTable1.Rows.Add(3, "Scott", 2)
    DataTable1.Rows.Add(4, "Jason")
    DataTable1.Rows.Add(5, "Julian")
    DataTable1.Rows.Add(6, "John", 5)
    DataTable1.Rows.Add(7, "Steve")
    DataTable1.Rows.Add(8, "George", 1)
    DataTable1.Rows.Add(9, "Robert", 1)
    DataTable1.Rows.Add(10, "Rodney", 8)

    Dim i As Integer

    For i = 0 To DataTable1.Rows.Count - 1
        Dim ID1 As String = DataTable1.Rows(i).Item("ID").ToString
        DataTable1.Rows(i).Item("LEVEL") = FindLevel(ID1, 0)
    Next
End Sub

Private Function FindLevel(ByVal ID As String, ByRef Level As Integer) As Integer
    Dim i As Integer

    For i = 0 To DataTable1.Rows.Count - 1
        Dim ID1 As String = DataTable1.Rows(i).Item("ID").ToString
        Dim Parent1 As String = DataTable1.Rows(i).Item("PARENT").ToString

        If ID = ID1 Then
            If Parent1 = "" Then
                Return Level
            Else
                Level += 1
                FindLevel(Parent1, Level)
            End If
        End If
    Next

    Return Level
End Function

Code for VB.NET WindowsForms application

Private Sub CreateTree()
    Dim MaxLevel1 As Integer = CInt(DataTable1.Compute("MAX(LEVEL)", ""))

    Dim i, j As Integer

    For i = 0 To MaxLevel1
        Dim Rows1() As DataRow = DataTable1.Select("LEVEL = " & i)

        For j = 0 To Rows1.Count - 1
            Dim ID1 As String = Rows1(j).Item("ID").ToString
            Dim Name1 As String = Rows1(j).Item("NAME").ToString
            Dim Parent1 As String = Rows1(j).Item("PARENT").ToString

            If Parent1 = "" Then
                TreeView1.Nodes.Add(ID1, Name1)
            Else
                Dim TreeNodes1() As TreeNode = TreeView1.Nodes.Find(Parent1, True)

                If TreeNodes1.Length > 0 Then
                    TreeNodes1(0).Nodes.Add(ID1, Name1)
                End If
            End If
        Next
    Next
End Sub

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    FillTestTable()
    CreateTree()
    TreeView1.ExpandAll()
End Sub

Code for ASP.NET application

Private Sub CreateTree()
    Dim MaxLevel1 As Integer = CInt(DataTable1.Compute("MAX(LEVEL)", ""))

    Dim i, j As Integer

    For i = 0 To MaxLevel1
        Dim Rows1() As DataRow = DataTable1.Select("LEVEL = " & i)

        For j = 0 To Rows1.Count - 1
            Dim ID1 As String = Rows1(j).Item("ID").ToString
            Dim Name1 As String = Rows1(j).Item("NAME").ToString
            Dim Parent1 As String = Rows1(j).Item("PARENT").ToString

            If Parent1 = "" Then
                TreeView1.Nodes.Add(New TreeNode(Name1, ID1))
            Else
                Dim Node1 As TreeNode = GetChildByValue(Parent1, TreeView1.Nodes)

                If Not Node1 Is Nothing Then
                    Node1.ChildNodes.Add(New TreeNode(Name1, ID1))
                End If
            End If
        Next
    Next
End Sub

Private Function GetChildByValue(ByVal ID1 As String, ByVal NodeCollection1 As TreeNodeCollection) As TreeNode
    For Each TreeNode1 As TreeNode In NodeCollection1
        If TreeNode1.Value = ID1 Then
            Return TreeNode1
        Else
            Dim TreeNode2 As TreeNode = GetChildByValue(ID1, TreeNode1.ChildNodes)

            If Not TreeNode2 Is Nothing Then
                Return TreeNode2
            End If
        End If
    Next

    Return Nothing
End Function

Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    FillTestTable()
    CreateTree()
    TreeView1.ExpandAll()
End Sub



回答2:


The big deal here is coming with a generic and adaptable enough algorithm capable of performing the required sorting. Once this is in place, writing the values into the TreeView is straightforward, just adding Nodes and ChildNodes.

    Dim NAME(10) As String
    Dim PARENT(10) As Integer
    Dim curID As Integer = 0

    curID = 1
    NAME(curID) = "Patrick [" & curID.ToString() & "]"
    PARENT(curID) = 0

    curID = curID + 1
    NAME(curID) = "Mark [" & curID.ToString() & "]"
    PARENT(curID) = 0

    curID = curID + 1
    NAME(curID) = "Scott [" & curID.ToString() & "]"
    PARENT(curID) = 2

    curID = curID + 1
    NAME(curID) = "Jason [" & curID.ToString() & "]"
    PARENT(curID) = 0

    curID = curID + 1
    NAME(curID) = "Julian [" & curID.ToString() & "]"
    PARENT(curID) = 0

    curID = curID + 1
    NAME(curID) = "John [" & curID.ToString() & "]"
    PARENT(curID) = 6

    curID = curID + 1
    NAME(curID) = "Steve [" & curID.ToString() & "]"
    PARENT(curID) = 0

    curID = curID + 1
    NAME(curID) = "George [" & curID.ToString() & "]"
    PARENT(curID) = 1

    curID = curID + 1
    NAME(curID) = "Robert [" & curID.ToString() & "]"
    PARENT(curID) = 1

    curID = curID + 1
    NAME(curID) = "Rodney [" & curID.ToString() & "]"
    PARENT(curID) = 8

    Dim completed As Boolean = False
    Dim firstIteration As Boolean = True
    Dim totIDs As Integer = 10

    Do
        curID = 0
        Do
            curID = curID + 1
            If (firstIteration) Then
                If (PARENT(curID) = 0 And TreeView1.FindNode(NAME(curID)) Is Nothing) Then
                    TreeView1.Nodes.Add(New TreeNode(NAME(curID)))
                End If
            Else
                If (PARENT(curID) > 0) Then
                    Dim targetNodes As TreeNodeCollection = TreeView1.Nodes
                    Dim count As Integer = 0

                    If (TreeView1.FindNode(NAME(curID)) Is Nothing) Then
                        For Each node As TreeNode In targetNodes
                            count = count + 1
                            If (node.Text.Contains("[" & PARENT(curID).ToString() & "]")) Then
                                node.ChildNodes.Add(New TreeNode(NAME(curID)))
                                Exit For
                            End If
                        Next
                    End If
                End If
            End If

        Loop While (curID < totIDs)

        If (firstIteration) Then
            firstIteration = False
        Else
            Exit Do 'Just two iterations
        End If
    Loop While (Not completed)

This code relies on two arrays (NAME (strings), which also includes [original position] and PARENT (integers)) and performs the inclusions until the "second level", that is, main nodes and first child nodes.

I guess that you will have enough information to understand how to deal with TreeView and to build an algorithm capable of performing the sorting you want.



来源:https://stackoverflow.com/questions/17746492/generate-treeview-control-dynamically-from-query-vb-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!