Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

store grandchild nodes text from TreeView on a List in C# (Winforms)

Let's say I have a treeview like this one:

1
|_2
  |_3
  |_4
|_5
  |_6
  |_7

I need to capture the text from all the nodes on level 2 of this tree.

If I do it like this:

List<string> list = new List<string>();
foreach(TreeNode node in treeView1.Nodes[0].Nodes[0].Nodes.Count)
{
       list.Add(node.Text);
}

this will only capture the first two grandchildren (3 and 4), but 6 and 7 won't be captured. Is there any way to iterate through a level of a treeview without taking the parents consideration??

like image 554
shingonati0n Avatar asked Dec 04 '25 13:12

shingonati0n


2 Answers

You can use Linq:

var nodes = treeView1.Nodes
               .Cast<TreeNode>()
               .SelectMany(n => n.Nodes.Cast<TreeNode>())
               .SelectMany(n => n.Nodes.Cast<TreeNode>());

foreach(TreeNode node in nodes)
{
       list.Add(node.Text);
}

Here is a general solution:

public static IEnumerable<TreeNode> GetNodesByDepth(TreeView treeView, int depth)
{
    var nodes = treeView.Nodes.Cast<TreeNode>();
    for (int i=0; i < depth; i++)
        nodes = nodes.SelectMany(n => n.Nodes.Cast<TreeNode>());
    return nodes;
}

A full example:

public class Program
{
    public static IEnumerable<TreeNode> GetNodesByDepth(TreeView treeView, int depth)
    {
        var nodes = treeView.Nodes.Cast<TreeNode>();
        for (int i = 0; i < depth; i++)
            nodes = nodes.SelectMany(n => n.Nodes.Cast<TreeNode>());
        return nodes;
    }
    static void Main(string[] args)
    {
        TreeView treeView = new TreeView();

        TreeNode node1 = new TreeNode("1");
        TreeNode node2 = new TreeNode("2");
        TreeNode node3 = new TreeNode("3");
        TreeNode node4 = new TreeNode("4");
        TreeNode node5 = new TreeNode("5");
        TreeNode node6 = new TreeNode("6");
        TreeNode node7 = new TreeNode("7");

        treeView.Nodes.Add(node1);
        node1.Nodes.Add(node2);
        node1.Nodes.Add(node5);
        node2.Nodes.Add(node3);
        node2.Nodes.Add(node4);
        node5.Nodes.Add(node6);
        node5.Nodes.Add(node7);

        Console.WriteLine("Method 1:");
        var nodes = treeView.Nodes
           .Cast<TreeNode>()
           .SelectMany(n => n.Nodes.Cast<TreeNode>())
           .SelectMany(n => n.Nodes.Cast<TreeNode>());

        foreach (TreeNode node in nodes)
        {
            Console.WriteLine(node.Text);
        }

        Console.WriteLine();
        Console.WriteLine("----------------");
        Console.WriteLine("Method 2:");
        nodes = GetNodesByDepth(treeView, 2);

        foreach (TreeNode node in nodes)
        {
            Console.WriteLine(node.Text);
        }
    }
}
like image 50
Ahmed KRAIEM Avatar answered Dec 09 '25 20:12

Ahmed KRAIEM


First of all, thanks to @Ahmed KRAIEM, his method is effective, even though I worked it out based on the hint from @Andrei V.

The solution i finally used was this:

for (int i = 0; i < trv.Nodes[0].Nodes.Count; i++)
            {
                foreach (TreeNode nodo in trv.Nodes[0].Nodes[i].Nodes)
                {
                    ordenes.Add(Convert.ToInt32(nodo.Text));
                }
            }

This get the nodes for a level also.

like image 28
shingonati0n Avatar answered Dec 09 '25 19:12

shingonati0n