如何获得的TreeView行为树节点,当你选中一个,它会检查其所有子树节点?子树、节点、当你、它会

2023-09-03 04:21:49 作者:最美不过初遇见

这是一样的大多数应用程序的行为。我以为TreeView的工作就像在默认情况下。

This is the same as how most apps behave. I thought TreeView worked like that by default.

有没有办法做到这一点,或者我必须得到一个树节点的所有这一切检查了孩子,并检查他们自己?

Is there a way to do this, or do I have to get all the children of a TreeNode that's checked and check them myself?

这是的WinForms。

This is winforms.

推荐答案

您需要自己做,这在另一方面是不是很辛苦:

You need to do it yourself, which on the other hand is not very hard:

private void TreeView_AfterCheck(object sender, TreeViewEventArgs e)
{
    SetChildrenChecked(e.Node, e.Node.Checked);
}

private void SetChildrenChecked(TreeNode treeNode, bool checkedState)
{
    foreach (TreeNode item in treeNode.Nodes)
    {
        item.Checked = checkedState;
    }
}

这需要照顾双方的检查,并取消选中所有儿童(无论有多少水平下降有可能是子节点)。

This takes care of both checking and unchecking all children (regardless of how many levels down there may be child nodes).

更新 扩展code样本还将检查/取消选中父节点,如果所有的子节点被选中或取消选中手动(不彻底的测试,也许可以更优雅的完成):

Update Expanded code sample that will also check/uncheck parent node if all of its child nodes are checked or unchecked manually (not thoroughly tested, could probably be done more elegantly):

private void TreeView_AfterCheck(object sender, TreeViewEventArgs e)
{
    SetChildrenChecked(e.Node, e.Node.Checked);

    if (e.Node.Parent != null)
    {
        bool setParentChecked = true;
        foreach (TreeNode node in e.Node.Parent.Nodes)
        {
            if (node.Checked != e.Node.Checked)
            {
                setParentChecked = false;
                break;
            }
        }
        if (setParentChecked)
        {
            e.Node.Parent.Checked = e.Node.Checked;
        }
    }
}

private void SetChildrenChecked(TreeNode treeNode, bool checkedState)
{
    foreach (TreeNode item in treeNode.Nodes)
    {
        if (item.Checked != checkedState)
        {
            item.Checked = checkedState;
        }
    }
}

if区块是在 SetChildrenChecked 方法添加将美元的当p $ pvent一个 StackOverflowException 在这里你检查与子节点的节点,他们得到遏制,而当最后一个被选中的父(你点击的那个)被cecked并再次触发 AfterCheck 事件(这让我吃惊了一下,我不希望事件被引发时,检查属性值不改变而只是被分配相同的值,它已经有了,但然后再次该事件被称为的 AfterCheck 的,不会的 AfterCheckedChanged 的)。

The if-block that is added in the SetChildrenChecked method will prevent a StackOverflowException in the case where you check a node with child nodes, they get checked, and when the last one is checked the parent (the one you clicked on) gets cecked and triggers the AfterCheck event again (which surprises me a bit; I would not expect the event to be raised when the Checked property value does not change but rather just gets assigned the same value it already had, but then again the event is called AfterCheck, not AfterCheckedChanged).