Question

I have a Treeview in my control that I am using the Tag property of to keep a copy of the object that it represents. This way when I click on any item in the tree I can easily get hold of the object it is referring to.

I am now adding a node to this and I want to quickly search the nodes via a property within the object stored.

So something similar to this:

class MyObject
{
    int Index;
}

IEnumerable<TreeNode> nodes = this.myTree.Nodes[0].Nodes.Cast<TreeNode>();
TreeNode currentNode = (from node in nodes
    let ts = node.Tag as MyObject
    where ts.Index == eqId.Index
    select node).First();

This works but I don't know if I am doing it properly or if there is a simpler solution. This searches all nodes of a particular level if I have got it right but can I make it stop once the first is found rather than searching the whole tree?

Is there an easier way to search within the Tags or is my approach just wrong to begin with?

Was it helpful?

Solution

Basically, this is ok. About the details:

If you want the enumeration to stop as soon a match is found, then you should write your own enumerator for the tree view:

public static IEnumerable<TreeNode> Descendants(this TreeNodeCollection c)
{
    foreach (var node in c.OfType<TreeNode>())
    {
        yield return node;

        foreach (var child in node.Nodes.Descendants())
        {
            yield return child;
        }
    }
}

and have

IEnumerable<TreeNode> nodes = this.myTree.Nodes.Desscendants();

I noticed that your code only searches for the root level. The code I provided searches every nodes, including descendants. If you do not want this, please remove the nested foreach loop.

Also, ensure you are using .FirstOrDefault instead of .First. Then you will have a null value instead of an exception if there is no match.

The simplest way IMHO is:

TreeNode currentNode = nodes.FirstOrDefault(n => (n.Tag as MyObject).Index == eqId.Index);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top