Daniel Santos
Daniel Santos

Reputation: 188

How to dynamicaly search for a string in all TreeView nodes expanding and collapsing nodes matching (or not) the search string?

I´m trying to implement dynamic search on a treeview component, and I´m almost done with it, except that since it´s a dynamic search based on the textchanged event of a textbox, the first characters of the search string are always found, so the search function expand all nodes because they are a valid match.

The thing is that as the search string becomes more complete, those nodes that were expanded when they had a match, now needs to be collapsed because they no longer match the search string... and this is not happening... I could not find yet a way to collapse and expand the nodes dinamically as the search string changes...

I have uploaded a video and the Visual Studio 2012 solution so you can take a look at it and see where I´m dropping the ball...

This is the code of my function that does the search: (You can see in the video it works as expected, so my problem is the expanding/collapsing of the nodes as they match(or not) the search string.

I´ve implemented some ideas in the "FindRecursive" function to collapse and expand the nodes, but it´s not working as expected. I managed to even put the control in an infinite loop due to my wrong logic.

Video showing the problem

Visual Studio 2012 Project + Test File

Private Sub txtFiltroIDs_TextChanged(sender As Object, e As EventArgs) Handles txtFilterToolIDs.TextChanged
        ClearBackColor()
        FindByText()
    End Sub

    Private Sub FindByText()
        Dim nodes As TreeNodeCollection = tviewToolIDs.Nodes
        Dim n As TreeNode
        For Each n In nodes
            FindRecursive(n)
        Next
    End Sub

    Private Sub FindRecursive(ByVal tNode As TreeNode)
        If txtFilterToolIDs.Text = "" Then
            tviewToolIDs.CollapseAll()
            tviewToolIDs.BackColor = Color.White
            ExpandToLevel(tviewToolIDs.Nodes, 1)
        Else
            Dim tn As TreeNode
            For Each tn In tNode.Nodes
                ' if the text properties match, color the item
                If tn.Text.Contains(txtFilterToolIDs.Text) Then
                    tn.BackColor = Color.Yellow
                    tn.EnsureVisible()        'Scroll the control to the item
                End If

                FindRecursive(tn)
            Next
        End If
    End Sub

    Private Sub ClearBackColor()
        Dim nodes As TreeNodeCollection
        nodes = tviewToolIDs.Nodes
        Dim n As TreeNode
        For Each n In nodes
            ClearRecursive(n)
        Next
    End Sub

    Private Sub ClearRecursive(ByVal treeNode As TreeNode)
        Dim tn As TreeNode
        For Each tn In treeNode.Nodes
            tn.BackColor = Color.White
            ClearRecursive(tn)
        Next
    End Sub

Upvotes: 1

Views: 7902

Answers (1)

Idle_Mind
Idle_Mind

Reputation: 39142

Following my initial comments, try something like:

Private Sub txtFiltroIDs_TextChanged(sender As Object, e As EventArgs) Handles txtFilterToolIDs.TextChanged
    tviewToolIDs.BeginUpdate()
    tviewToolIDs.CollapseAll()
    ClearBackColor()
    FindByText()
    tviewToolIDs.EndUpdate()
    tviewToolIDs.Refresh()
End Sub

Upvotes: 1

Related Questions