2

Hello and thanks in advance for your help.

I have a treeview that is populated from a HDD folder collection. Its structure is similar to the following (however the structure is dynamic):

My Disk:
|
|--folder1(tag:folder)
|  |--subfolder1(tag:folder)
|--folder2(tag:folder)
|--folder3(tag:folder)
|--folder4(tag:folder)
   |file1(tag:file)

I would like to delete all nodes from the tree that do not contain nodes with the tag "file" (basically empty folders). I would like the resulting tree structure to look like this:

My Disk:
|--folder4(tag:folder)
   |file1(tag:file)

The best that I have come up with is the following:

Private Sub deleteNode(byval nc as TreeNodeCollection)
 For Each tn As TreeNode In nc
  'delete node if it applies
        If tn.Tag = "folder" Then
            If tn.Nodes.Count = 0 Then
                 nc.Remove(tn)
            End If
        End If

        If tn.Nodes.Count > 0 Then
             deleteNode(tn.Nodes)
        End If
    Next
End Sub

I call the sub as follows:

deleteNode(treeview1.Nodes(0).Nodes)

However, the above is not working properly. It deletes only some nodes and not all the targeted nodes. Could you please help me out by fixing my sub?

Many thanks

mazrabul
  • 295
  • 1
  • 5
  • 17

2 Answers2

4

As far as I know, you can't edit the collection you're enumerating, so that it removes some nodes is also impressive.

You might wanna try another approach:

Private Sub RemoveEmptyFolderNodes(ByVal nc as TreeNodeCollection)
    For i As Integer = nc.Count - 1 To 0 Step -1
        If nc(i).Nodes.Count > 0 Then
            RemoveEmptyFolderNodes(nc(i).Nodes)
        End If
        If nc(i).Nodes.Count = 0 AndAlso nc(i).Tag.ToString() = "folder" Then
            nc.RemoveAt(i)
        End If                
    Next
End Sub

This is untested.

Community
  • 1
  • 1
Bobby
  • 11,419
  • 5
  • 44
  • 69
  • 1
    Or even better "For i As Integer = nc.Count - 1 to 0 Step -1". Then there is no more need for "i -= 1" in the elseIf part – k3b Dec 16 '10 at 12:37
  • Hi and thank you for your response. I've tried the code but it didn't completely work. It deleted most targeted nodes except node(0). Either because it is handeling top level nodes only or because the 'for' loop isn't 100% correct. I'm still trying to figure it out. – mazrabul Dec 16 '10 at 12:53
  • @mazrabul: Does nc(0) really meet the criteria, because it is for sure checked. – Bobby Dec 16 '10 at 12:56
  • @Bobby: I have edited the original question to reflect exactly the treeview structure that I tested. 'folder1' is not deleted, however the subfolder inside it is deleted. – mazrabul Dec 16 '10 at 13:04
  • @mazrabul: Ohhhhhh...now I understand...I've edited my answer. – Bobby Dec 16 '10 at 13:07
  • @Bobby: Your last edit solved my problem. I am extremely grateful for your help. Many Thanks. – mazrabul Dec 16 '10 at 13:12
0

The treeview is initially populated by our program?

If so simply don't add the nodes with that tag.

If not, the for each loop is a problem since the treenode collection is been changed every time you call the remove node function.

I've solved this by creating a collection to store the keys to be removed and AFTER the for each loop you may safely remove the nodes you want. gl.

For example:

Dim nNd As Node
Dim toDel As New Collection

For Each nNd In tvSS.Nodes
    If nNd.tag="whatuwant" Then toDel.Add (nNd.Key)
Next
Do While toDel.Count > 0
    tvSS.Nodes.Remove (toDel.Item(1))
    toDel.Remove (1)
Loop
Set toDel = Nothing
Paulo Bueno
  • 2,499
  • 6
  • 42
  • 68
  • thanks for the code. But my main problem is with the 'for' loop. How can I make it target the nodes I want recursively and not just the top level... – mazrabul Dec 16 '10 at 12:54
  • The first loop interacts with ALL nodes in tvSS. So be happy... ;) – Paulo Bueno Dec 16 '10 at 13:54