TreeView search

c#, search, treenode, treeview, winforms

Solution

Something like the following should be fine to add to your Form's code.

    private List<TreeNode> CurrentNodeMatches = new List<TreeNode>();

    private int LastNodeIndex = 0;

    private string LastSearchText;


    private void button1_Click(object sender, EventArgs e)
    {


        string searchText = this.textBox1.Text;
        if (String.IsNullOrEmpty(searchText))
        {
            return;
        };


        if (LastSearchText != searchText)
        {
            //It's a new Search
            CurrentNodeMatches.Clear();
            LastSearchText = searchText;
            LastNodeIndex = 0;
            SearchNodes(searchText, treeView1.Nodes[0]);
        }

        if (LastNodeIndex >= 0 && CurrentNodeMatches.Count > 0 && LastNodeIndex < CurrentNodeMatches.Count)
        {
            TreeNode selectedNode = CurrentNodeMatches[LastNodeIndex];
            LastNodeIndex++;
            this.treeView1.SelectedNode = selectedNode;
            this.treeView1.SelectedNode.Expand();
            this.treeView1.Select();

        }
    } 

    private void SearchNodes(string SearchText, TreeNode StartNode)
    {
        TreeNode node = null;
        while (StartNode != null)
        {
            if (StartNode.Text.ToLower().Contains(SearchText.ToLower()))
            {
                CurrentNodeMatches.Add(StartNode);
            };
            if (StartNode.Nodes.Count != 0)
            {
                SearchNodes(SearchText, StartNode.Nodes[0]);//Recursive Search 
            };
            StartNode = StartNode.NextNode;
        };

    }

There are two parts to this;

Collect all of the nodes into a `List<TreeNode>`

Page through the `List<TreeNode>` if the search hasn't changed. If the Search has changed, clear out the list and reset the indexing.

I've tested this with Windows Forms running under .Net 4 - it pages through each node in a TreeView that contain the search text, 1 by 1 until it reaches the last node.

Problem

This function find only first node in treeview, that contains `SearchText`. ``` private TreeNode SearchNode(string SearchText,TreeNode StartNode) { TreeNode node=null; while (StartNode!= null) { if (StartNode.Text.ToLower().Contains(SearchText.ToLower())) { node = StartNode; break; }; if (StartNode.Nodes.Count != 0) { node=SearchNode(SearchText, StartNode.Nodes[0]);//Recursive Search if (node != null) { break; }; }; StartNode = StartNode.NextNode; }; return node; } private void button1_Click(object sender, EventArgs e) { string SearchText = this.textBox1.Text; if (SearchText == "") { return; }; TreeNode SelectedNode = SearchNode(SearchText, treeView1.Nodes[0]); if (SelectedNode != null) { this.treeView1.SelectedNode = SelectedNode; this.treeView1.SelectedNode.Expand(); this.treeView1.Select(); }; } ``` How should I change it, so the function will able to find not only the first node, but all of them, every time when I click `button1`, it'll find next node till the end, and then it starts from the beginning? So I should search not from `TreeView1.Nodes[0]`, but from `TreeView1.SelectedNode`...

Original source