是否可以在树视图中创建特定于单个节点的选中事件触发器?

Can you create a checked event trigger specific to a single node in a Tree View?

提问人:Walltumbler 提问时间:7/16/2023 最后编辑:CharliefaceWalltumbler 更新时间:7/16/2023 访问量:36

问:

如何遍历“树视图”,以便在检查父节点时自动检查所有子节点。然后,用户应该根据需要取消选中每个子节点。如果取消选中所有子节点,则应自动取消选中父节点。

以下代码的问题在于,有办法区分是父节点还是子节点触发了事件。代码只能查看树视图在事件触发时的状态。因此,使用此功能,无法再取消选中子节点。我能想到的唯一方法是保存树视图的先前状态以比较它们以查看检查了哪个节点、父节点或其他节点,然后从那里开始。我希望有一种更简单的方法。

感谢您的帮助!

private void CorridorList_AfterCheck(object sender, TreeViewEventArgs e)
    {
        this.CorridorList.AfterCheck -= CorridorList_AfterCheck;
        foreach (TreeNode node in this.CorridorList.Nodes)
        {
            // checks all child nodes if parent node is checked. 
            TreeNodeCollection ChildnodeCol =  node.Nodes;
            {
                if (node.Checked && (!ChildnodeCol[0].Checked && !ChildnodeCol[1].Checked) )
                {  
                    ChildnodeCol[0].Checked = true;
                    ChildnodeCol[1].Checked = true;
                    node.Expand();
                }
            }
        }
        this.CorridorList.AfterCheck += CorridorList_AfterCheck;
    }

树视图示例

C# WinForms 事件 TreeView 节点

评论

0赞 dr.null 7/16/2023
stackoverflow.com/a/65425515/14171304

答:

0赞 Charlieface 7/16/2023 #1

您可以使用它来检查触发它的原因。但是,纾困意味着你不能使用事件本身来递归。您需要创建一个单独的函数来递归。e.Action

private void CorridorList_AfterCheck(object sender, TreeViewEventArgs e)
{
    if (e.Action == TreeViewAction.Unknown)    // was triggered by code
        return;

    CheckSubNodes(e.Node);
}

void CheckSubNodes(TreeNode node)
{
    foreach (TreeNode node in node.Nodes)
    {
        if (!node.Checked)
        {
            node.Checked = true;
            node.Expand();  // do you need to expand also??
            // checks all child nodes if parent node is checked. 
            CheckSubNodes(node);
        }
    }
}
0赞 Walltumbler 7/16/2023 #2

谢谢!我不明白事件参数是如何工作的。这真的帮助了我。这是解决问题的代码。谢谢!

 //when parent node is checked
        TreeNode Node = e.Node;
        if (Node.Checked && Node.Nodes.Count !=0)
        {
            Node.Nodes[0].Checked = true;
            Node.Nodes[1].Checked = true;
            Node.Expand();
        }

        //when child node is unckeded, wil check if other node is unchecked, then ucheck parent node. 
        if(!Node.Checked && Node.Nodes.Count == 0)
        {
            TreeNode ParentNode = Node.Parent;
            if (!ParentNode.Nodes[0].Checked && !ParentNode.Nodes[1].Checked)
            {
                ParentNode.Checked = false;
            }
        }