web-dev-qa-db-ja.com

ツリービューでチェックされたすべてのノードとそのサブノードのリストを取得します

ツリービューリストのチェックボックスがあり、リストにはノード、サブノード、場合によってはサブノードのサブノードが含まれています。ユーザーがいくつかのアイテムをチェックするとき、私は選択されたアイテムのリストを取得したいです。

これについて、メインノードの選択されたアイテムのみを取得する理由:

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

ツリービュー全体をトラバースして、サブノードのチェック済みアイテムを取得するにはどうすればよいですか?

7
Josef

LINQが好きな場合は、ツリービュー全体をトラバースする拡張メソッドを作成できます。

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

次に、LINQを使用して必要なすべての操作を実行できます。あなたの場合、選択したノードのリストを取得するのは簡単です。

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

このアプローチの利点は、一般的であるということです。

ただし、Descendant()メソッドはツリー全体をトラバースするため、親にチェックされるノードのみを処理するため、@ mybirthnameで指定された回答よりも効率が少し低下する可能性があります。あなたのユースケースにこの制約が含まれているかどうかはわかりません。

編集:@mybirthnameの回答が編集されました。同じことをしています。これで、ループとLINQソリューションができました。どちらも再帰的です。

14
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);
    }
} 
_

子のメモを振り返ることはありません。再帰を使用してそれを行うことができます。

このような方法が必要です!コードでGetCheckedNodes(tvSastavnica.Nodes)を1回呼び出すだけで、チェックされたすべてのノードが表示されます。

7
mybirthname

私のやり方:

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

        LookupChecks(node.Nodes, list);
    }
}

使用法:

var list = new List<TreeNode>();
LookupChecks(TreeView.Nodes, list);
3
IlPADlI