如何测试TreeView节点和/或节点子项是否被选中?

3

我有一个包含节点和带子节点的TreeView列表的程序,它们都启用了复选框属性。 我需要知道如何检查哪些节点/子节点已经被勾选。到目前为止,我已经成功测试了父节点,但没有测试过子节点:

//this  will turn black any node that is checked, doesn't affect the children though
    TreeNodeCollection nodes = this.treeView1.Nodes;
                foreach (TreeNode n in nodes)
                {
                    if (n.Checked)
                    {
                        n.BackColor = Color.Black;   
                    }
                }

我该如何让它检查父节点以及子节点?我已经搜索过了,但没有找到任何可以为我澄清这个问题的东西。


除非您正在OwnerDrawing treeview,否则TreeNode.BackColor将不起作用。 - Sam Axe
不确定那是什么意思,不过对我来说它运行良好。 - Fuzz Evans
哎呀,我本来以为 TreeNode.backColor 没有任何作用。原来是我的错。谢谢你提醒我。 - Sam Axe
https://dev59.com/I23Xa4cB1Zd3GeqPha-S#14531278 - Parimal Raj
4个回答

5
您可以定义一个递归函数来标记所有已选项目:
private static void MarkSelectedNodes(TreeNodeCollection nodes)
{
    foreach (TreeNode n in nodes)
    {
        if (n.Checked)
            n.BackColor = Color.Black;

        MarkSelectedNodes(n.Nodes);
    }
}

然后这样调用:

MarkSelectedNodes(treeView1.Nodes);

空值检查?如果节点不为空 - user959729
@user959729:如果有人传递null,节点将只是null。如果您使用Treview.NodesTreeNode.Nodes,则永远不会得到null。 - Sam Axe
就像Dan-o所解释的那样,TreeNodeNodes集合默认不为null,而是一个空的TreeNodeCollection,因此上面的代码将可以正常运行。 - Cristian Lupascu

1
你可以“展开”递归以提高性能并避免堆栈溢出:
private static void MarkSelectedNodes(TreeNodeCollection nodes)
{
    Stack<TreeNode> toProcess =
        new Stack<TreeNode>(nodes.OfType<TreeNode>());

    while (toProcess.Count != 0)
    {
        TreeNode node = toProcess.Pop();
        if (node.Checked)
            node.BackColor = Color.Black;

        foreach (TreeNode child in node.Nodes)
            toProcess.Push(child);
    }
}

0

你需要再往下一级进入子节点。相同的代码,只需另一个循环:

TreeNodeCollection nodes = this.treeView1.Nodes;
        foreach (TreeNode n in nodes)
        {
            foreach (TreeNode c in n.Nodes)
            {
                if (c.Checked)
                {
                    c.BackColor = Color.Gray;
                }
            }
            if (n.Checked)
            {
                n.BackColor = Color.Black;
            }
        }

递归更好,因为它可以支持任何节点深度。 - Sam Axe
更多的是一个“为什么它不工作”而不是一个可用的例子。不确定为什么会被踩,因为它毕竟是一个答案。 - Lee Harrison

0
    public static IEnumerable<TreeNode>
                           GetAllCheckedChildNodes(TreeNode node)
    {
        foreach (TreeNode tmpNode in node.Nodes)
        {
            if (tmpNode.Checked)
            {
                yield return tmpNode;
            }

            foreach (var x in GetAllCheckedChildNodes(tmpNode))
            {
                yield return x;
            }
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var checkedNodes = GetAllheckedChildNodes(MyRootNode);
        foreach (TreeNode checkedNode in checkedNodes)
        {
            checkedNode.BackColor = Color.Black;
        }
    }

这应该可以完成工作! - Parimal Raj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接