We have a legacy application written in VB6 using the default Microsoft TreeView
control to display hierarchical data. Since there's a lot of information in this TreeView
we thought about implementing a small filter/search possibility for the users.
The first attempt was to toggle the visibility and only make nodes (and their parents) visible, that match the defined search. But that was impossible, since the default Microsoft TreeView
control doesn't allow their nodes to be visible or invisible.
So the second attempt is to traverse all the nodes in the tree and ensure a node's visibility when it matches the defined search (and stop traversing). When the found node isn't the one the user is looking for he can "continue" the search and look for the next node that matches his criteria.
This works quite good so far, except for one little problem. The search doesn't work from top to bottom, since the tree is filled with data in random sort order and then sorted by setting the Sorted
property of each node (legacy code). So the search is going through the randomly added nodes and the found nodes "jump" between the top level nodes (the Nodes
collection of the TreeView
contains all the nodes in the order they were added, not just the top level nodes and not in the order they are presented to the user).
Is there any way to get all the nodes of the tree in the order they are shown to the user? I don't like to change the legacy code that is filling the tree with data, and sorting the data before it is added to the TreeView
might affect performance.
Please be aware that I'm talking about an application written in VB6, so there's no such thing as LINQ to traverse the nodes in the desired order.
Here's my searching code so far:
Private Sub cmdSearch_Click()
Dim oMatch As Node
Set oMatch = GetNextMatch
If Not (oMatch Is Nothing) Then
oMatch.EnsureVisible
oMatch.Selected = True
Me.TreeView1.SelectedItem = oMatch
Me.TreeView1.SetFocus
End If
End Sub
Private Function GetNextMatch() As Node
Dim lIndex As Long
Dim oResult As Node
For lIndex = mlLastFoundIndex + 1 To Me.TreeView1.Nodes.Count
If IsMatch(Me.TreeView1.Nodes(lIndex).Text) Then
Set oResult = Me.TreeView1.Nodes(lIndex)
mlLastFoundIndex = lIndex
Exit For
End If
Next lIndex
Set GetNextMatch = oResult
End Function
Private Sub txtSearch_Change()
mlLastFoundIndex = 0
End Sub