C# 如何获得TreeNodes的TreeView行为,即当您检查一个树节点时,它会检查其所有子树节点?

C# 如何获得TreeNodes的TreeView行为,即当您检查一个树节点时,它会检查其所有子树节点?,c#,.net,winforms,treeview,C#,.net,Winforms,Treeview,这与大多数应用程序的行为相同。我以为TreeView在默认情况下就是这样工作的 有没有办法做到这一点,或者我必须让一个树节点的所有子节点都经过检查,然后自己检查 这是winforms。您需要自己动手,另一方面,这并不难: private void TreeView_AfterCheck(object sender, TreeViewEventArgs e) { SetChildrenChecked(e.Node, e.Node.Checked); } private void SetC

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

有没有办法做到这一点,或者我必须让一个树节点的所有子节点都经过检查,然后自己检查


这是winforms。

您需要自己动手,另一方面,这并不难:

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;
    }
}
这将同时检查和取消选中所有子节点(不管下面可能有多少级别的子节点)

更新
扩展的代码示例,如果手动检查或取消检查父节点的所有子节点,则也将检查/取消检查父节点(未完全测试,可能会做得更优雅):


SetChildrenChecked
方法中添加的if块将防止
StackOverflowException
在您检查带有子节点的节点时,它们会被检查,并且在最后一个节点被检查时,父节点(您单击的那个)会被检查并再次触发
AfterCheck
事件(这让我有点吃惊;我不希望在
Checked
属性值没有更改,而只是被分配了它已经具有的相同值时引发该事件,但是该事件再次被称为AfterCheck,而不是AfterCheckedChanged).

如果用户手动检查所有子节点,这是否也会检查节点?@dtb:不,它不会向上触发。这一点很好。将更新答案。实际上,如果用户检查父节点,然后取消选中子节点,则父节点将以不同方式检查,以显示其子节点未全部检查?@Joan:AFAIK the treeView本机不支持中间选中状态。这可以通过播放树节点图标来实现(使用图像而不是复选框来可视化选中状态)。但这需要更多的编码。我遇到了与@JoanVenge相同的问题,即当您取消选中子复选框时,父复选框的状态不正确。
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;
        }
    }
}