Search code examples
c#winformssearchtreeviewtreenode

TreeView search


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...


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;

    1. Collect all of the nodes into a List<TreeNode>

    2. 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.