Tree node filtering with List I had a question about filtering tree view and returning just first match.

I've tried to create list&lt;treenode&gt; and change the code.  Is it possible improve the below code for finding nodes and child nodes that match my criteria?

private List&lt;TreeNode&gt; FindNodeByValue(TreeNodeCollection nodes, string searchstring)
{

    // Loop through the tree node collection
    List&lt;TreeNode&gt; nodelist=new List&lt;TreeNode&gt;();

    foreach (TreeNode node in nodes)
    {
        // Does the value match the search string?
        if (node.Value.ToUpper().Contains (searchstring.ToUpper()))
            // Yes it does match - return it
            nodelist.Add(node);
        //  return nodelist;
        else
        {
            // No it does not match - search any child nodes of this node
            List&lt;TreeNode&gt; childNode = SearchChildNodes(node, searchstring);
            // If the childNode is not null it was a match
            if (childNode != null)
                // Return the matching node
                return childNode;
        }
    }
    // If the matching node is not found return null
    return null;
}

/// &lt;summary&gt;
/// This method searches a node's ChildNodes collection to find a matching value
/// with the incoming search string
/// It will iteratively call itself as it drills into each nodes child nodes (if present)
/// &lt;/summary&gt;
/// &lt;param name="parentNode"&gt;Parent node to search for a match&lt;/param&gt;
/// &lt;param name="searchstring"&gt;string to be matched with the Nodes Value property&lt;/param&gt;
/// &lt;returns&gt;Treenode of the matching node if found.  If not found it will be null&lt;/returns&gt;
private List&lt;TreeNode&gt; SearchChildNodes(TreeNode parentNode, string searchstring)
{
    List&lt;TreeNode&gt; nodelist2 = new List&lt;TreeNode&gt;();
    // Loop through the child nodes of the parentNode passed in
    foreach (TreeNode node in parentNode.ChildNodes)
    {
        // Does the value match the search string?
        if (node.Value.ToUpper().Contains(searchstring.ToUpper()))
            // Yes it does match - return it
            nodelist2.Add(node);
            //return nodelist2;
            //return node;
        else
        {
            // No it does not match - recursively search any child nodes of this node
            List&lt;TreeNode&gt; childNode = SearchChildNodes(node, searchstring);
            // If the childNode is not null it was a match
            if (childNode != null)
                childNode.Add(node);
                // Return the matching node
                return childNode;
        }
    }
    // If the matching node is not found OR if there were no child nodes then return null
    return null;
}

protected void Button1_Click(object sender, EventArgs e)
{
    TreeNode trnode=FindNodeByValue(TreeView1.Nodes, fieldFilterTxtBx.Text);
    if (trnode != null)
    {
        TreeView1.Nodes.Clear();
       // TreeNode newnode = new TreeNode("Detail Engineering");
       // TreeView1.Nodes.Add(newnode);
        TreeView1.Nodes.Add(trnode);
        TreeView1.ExpandAll();
    }
    else
    {
        Label1.Text = "No file found";
    }
}
Currently you do not search sub nodes it a matching parent is found. This code fixes that problem and also simplifies the code by removing the unnecessary SearchChildNodes function. If you only care about the first match use var node = FindNodeByValue(TreeView1.Nodes, fieldFilterTxtBx.Text).FirstOrDefault();

private IEnumerable&lt;TreeNode&gt; FindNodeByValue(TreeNodeCollection nodes, string searchstring)
{
    foreach (TreeNode node in nodes)
    {
        if (node.Value.IndexOf(searchstring, 
              StringComparison.CurrentCultureIgnoreCase) &gt;= 0)
            yield return node;
        else
        {
            foreach (var subNode in FindNodeByValue(node.ChildNodes, searchstring))
                yield return subNode;
        }
    }
}