Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get list of all checked nodes and its subnodes in treeview

I have a treeview list check boxes and the list contains nodes, subnodes and in some cases subnode of subnode. When user check some items i want to get list of selected items.

On this why I get only selcted items of main node:

 foreach (System.Windows.Forms.TreeNode aNode in tvSastavnica.Nodes)
        {
            if (aNode.Checked == true)
            {
                Console.WriteLine(aNode.Text);
            }
        }

How to travers through whole treeview and get checked items in subnodes?

like image 705
Josef Avatar asked Oct 24 '14 06:10

Josef


Video Answer


3 Answers

my way:

void LookupChecks(TreeNodeCollection nodes, List<TreeNode> list)
{
    foreach (TreeNode node in nodes)
    {
        if (node.Checked)
            list.Add(node);

        LookupChecks(node.Nodes, list);
    }
}

useage:

var list = new List<TreeNode>();
LookupChecks(TreeView.Nodes, list);
like image 54
IlPADlI Avatar answered Nov 06 '22 23:11

IlPADlI


If you like LINQ, you can create an extension method that traverses the whole treeview:

internal 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;
        }
    }
}

Then you can perform every operations you want using LINQ. In your case, getting a list of selected nodes is easy:

var selectedNodes = myTreeView.Nodes.Descendants()
                    .Where(n => n.Checked)
                    .Select(n => n.Text)
                    .ToList();

An advantage of this approach is it is generic.

However, because the Descendant() method traverses the whole tree, it might be a bit less efficient than the answer given by @mybirthname because it only cares about nodes that are checked with their parents. I dont known if your use case includes this constraint.

EDIT: Now @mybirthname answer has been edited, it is doing the same. Now you have the loop and the LINQ solution, both are recursive.

like image 34
Larry Avatar answered Nov 06 '22 22:11

Larry


public void GetCheckedNodes(TreeNodeCollection nodes)
{
    foreach(System.Windows.Forms.TreeNode aNode in nodes)
    {
         //edit
         if(!aNode.Checked)
             continue;

         Console.WriteLine(aNode.Text);

         if(aNode.Nodes.Count != 0)
             GetCheckedNodes(aNode.Nodes);
    }
} 

You don't make look back into the child notes, using recursion you can do it.

You need method like this ! In your code just call once GetCheckedNodes(tvSastavnica.Nodes) and all checked nodes should be displayed !

like image 42
mybirthname Avatar answered Nov 06 '22 21:11

mybirthname