【问题标题】:Get list of all checked nodes and its subnodes in treeview获取树视图中所有选中节点及其子节点的列表
【发布时间】:2014-12-19 23:25:05
【问题描述】:

我有一个树视图列表复选框,该列表包含节点、子节点,在某些情况下还包含子节点的子节点。当用户检查某些项目时,我想获取所选项目的列表。

关于这为什么我只得到主节点的选定项:

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

如何遍历整个树视图并获取子节点中的选中项?

【问题讨论】:

  • 要了解递归,首先你必须了解递归
  • 检查我的解决方案,如果有什么不清楚的地方告诉我!

标签: c# winforms treeview


【解决方案1】:

如果你喜欢LINQ,你可以创建一个遍历整个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;
        }
    }
}

然后您可以使用 LINQ 执行您想要的所有操作。在您的情况下,获取选定节点的列表很容易:

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

这种方法的一个优点是它是通用的。

但是,由于 Descendant() 方法遍历整个树,它可能比@mybirthname 给出的答案效率低一些,因为它只关心与其父节点一起检查的节点。我不知道您的用例是否包含此约束。

编辑:现在@mybirthname 答案已被编辑,它正在做同样的事情。现在你有了循环和 LINQ 解决方案,它们都是递归的。

【讨论】:

  • 正是我想要的!
【解决方案2】:
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) 并应显示所有选中的节点!

【讨论】:

  • 您的解决方案非常有效,但它基于这样一个假设,即已检查的子节点也必须检查其父节点。不幸的是,如果检查了深层子节点而未检查其父节点,它将无法正常工作。因为问题中没有提出这个约束,所以我建议删除“继续”语句并恢复 Checked 测试,以便遍历整个树。
  • @Larry 你是对的,我会进行编辑!感谢您的评论!
  • 我很想在您的帖子中看到这两种方法。我认为在某些情况下,如果不检查父节点 - 我们不关心子节点。太糟糕了,你没有离开原版 - 我试着检查我是否能找到编辑历史 - 但我不能..
  • @Ken : 只需点击上面的"edited At" 链接即可获得更改历史记录
【解决方案3】:

我的方式:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多