vb.nettreeviewwindows-forms-designertree-nodes

Removing multiple nodes in TreeView with recursive function


I have a pre-built TreeView control. I want to remove the nodes as a permission set according to values that are saved in a database. I used a recursive method to delete the nodes, but some nodes remain and don't get deleted. Here's my code:

Private Sub setNodes()
    For Each nd As TreeNode In TreeView1.Nodes
        If nd.Name = "Students" AndAlso row.Item("CanAddStudents") = False AndAlso row.Item("CanViewStudents") = False AndAlso row.Item("CanImportStudents") = False Then
            nd.Remove()
            nd.Tag = False
        End If
        If Not nd.Tag = False Then
            setNodes(nd)
        End If
        nd.Tag = True
    Next
End Sub

Private Sub setNodes(ByVal nd As TreeNode)
    For Each childNd As TreeNode In nd.Nodes
        If childNd.Name = "Registration" AndAlso row.Item("CanAddStudents") = False Then
            childNd.Remove()
            childNd.Tag = False
        ElseIf childNd.Name = "View_Registration" AndAlso row.Item("CanViewStudents") = False Then
            childNd.Remove()
            childNd.Tag = False
        ElseIf childNd.Name = "Import_Student" AndAlso row.Item("CanImportStudents") = False Then
            childNd.Remove()
            childNd.Tag = False
        End if
    Next
    If Not childNd.Tag = False Then
        setNodes(childNd)
    End If
    childNd.Tag = True
End Sub

This code works on single parent nodes and their child nodes, but it does not work when there is more than 1 parent nodes. If there are 3 parents nodes, then one of those parent nodes will not delete.

I changed my code as below.

Private Sub RemoveNodes(ByVal nc As TreeNodeCollection)
    For i As Integer = nc.Count - 1 To 0 Step -1
        If nc(i).Nodes.Count > 0 Then
            RemoveNodes(nc(i).Nodes)
        End If
        If nc(i).Name = "Registration" AndAlso row.Item("CanAddStudents") = False Then
            nc.RemoveAt(i)
        ElseIf nc(i).Name = "View_Registration" AndAlso row.Item("CanViewStudents") = False Then
            nc(i).Remove()
        ElseIf nc(i).Name = "Import_Student" AndAlso row.Item("CanImportStudents") = False Then
            nc(i).Remove()
        ElseIf nc(i).Name = "Students" AndAlso row.Item("CanAddStudents") = False AndAlso row.Item("CanViewStudents") = False AndAlso row.Item("CanImportStudents") = False Then
            nc(i).Remove()
        End If
    Next
End Sub

Solution

  • It's hard to say just by looking at this code, but one thing that does look odd to me is that in the setNodes(TreeNode) method, you only have it calling itself recursively on the last child node. If you want to do it for each node, you need to move the bottom If statement up into your For loop. For instance:

    For Each childNd As TreeNode In nd.Nodes
        If childNd.Name = "Registration" AndAlso row.Item("CanAddStudents") = False Then
            childNd.Remove()
            childNd.Tag = False
        ElseIf childNd.Name = "View_Registration" AndAlso row.Item("CanViewStudents") = False Then
            childNd.Remove()
            childNd.Tag = False
        ElseIf childNd.Name = "Import_Student" AndAlso row.Item("CanImportStudents") = False Then
            childNd.Remove()
            childNd.Tag = False
        End if
    
        'Put recursive call inside loop
        If Not childNd.Tag = False Then
            setNodes(childNd)
        End If
        childNd.Tag = True
    Next