C# 带复选框的Winform TreeView-仅更新可见节点

C# 带复选框的Winform TreeView-仅更新可见节点,c#,winforms,treeview,checkbox,C#,Winforms,Treeview,Checkbox,我是新来的,几乎到处都在寻找我的问题的答案,但毫无结果。我希望这里有人能帮忙 我有一个WinForm应用程序,在其中我使用树状视图显示选定根文件夹下的文件夹结构。树视图已启用复选框。当我选中或取消选中树节点上的复选框时,该树节点下的任何可见节点也会发生变化——到目前为止还不错 问题是,当我进一步展开节点时,新的可见节点没有更新到正确的状态 我使用以下递归例程执行更新: private void CheckAllChildNodes(TreeNode treeNode, bool node

我是新来的,几乎到处都在寻找我的问题的答案,但毫无结果。我希望这里有人能帮忙

我有一个WinForm应用程序,在其中我使用树状视图显示选定根文件夹下的文件夹结构。树视图已启用复选框。当我选中或取消选中树节点上的复选框时,该树节点下的任何可见节点也会发生变化——到目前为止还不错

问题是,当我进一步展开节点时,新的可见节点没有更新到正确的状态

我使用以下递归例程执行更新:

    private void CheckAllChildNodes(TreeNode treeNode, bool nodeChecked)
    {
        foreach (TreeNode node in treeNode.Nodes)
        {
            node.Checked = nodeChecked;
            if (node.Nodes.Count > 0)
            {
                // If the current node has child nodes, call the
                // CheckAllChildNodes method recursively.
                CheckAllChildNodes(node, nodeChecked);
            }
        }
    }
从该事件处理程序调用它:

    private void FileTreeView_AfterCheck(object sender, TreeViewCancelEventArgs e)
    {
        // The code only executes if the user caused the checked state to change.
        if (e.Action == TreeViewAction.ByMouse)
        {
            if (e.Node.Nodes.Count > 0)
            {
                // Calls the CheckAllChildNodes method, passing in the current
                // checked value of the TreeNode whose checked state changed.
                CheckAllChildNodes(e.Node, e.Node.Checked);
            }
        }
    }
递归函数似乎只关心在执行时可见的树节点

如果有人能给出错误的线索,以及如何纠正错误,我们将不胜感激

提前谢谢

致以最良好的祝愿


L.Hummel

我试图复制你在代码中可能正在做的事情。请你使用此代码并确认它是否正常工作,或者你正面临相同的问题

 private void PopulateFolderTreeView(string directories, TreeNode parentNode)
            {
                string[] directoriesArray = Directory.GetDirectories(directories);
                string[] filesArrays = Directory.GetFiles(directories);
                if (directoriesArray.Length != 0)
                {
                    foreach (string currentDirectory in directoriesArray)
                    {
                        TreeNode myNode = new TreeNode(Path.GetFileNameWithoutExtension(currentDirectory));
                        if (parentNode == null)
                        {
                            treeView1.Nodes.Add(myNode);
                        }
                        else
                        {
                            parentNode.Nodes.Add(myNode);
                        }
                        PopulateFolderTreeView(currentDirectory, myNode);
                    }

                }
                if (filesArrays.Length != 0)
                {
                    foreach (string currentFile in filesArrays)
                    {
                        TreeNode myNode = new TreeNode(Path.GetFileName(currentFile));
                        if (parentNode == null)
                        {
                            treeView1.Nodes.Add(myNode);
                        }
                        else
                        {
                            parentNode.Nodes.Add(myNode);
                        }
                        //PopulateTreeView(currentDirectory, myNode);
                    }

                }
            }



     private void CheckAllChildNodes(TreeNode treeNode, bool nodeChecked)
            {
                foreach (TreeNode node in treeNode.Nodes)
                {
                    node.Checked = nodeChecked;
                    if (node.Nodes.Count > 0)
                    {
                        // If the current node has child nodes, call the
                        // CheckAllChildNodes method recursively.
                        CheckAllChildNodes(node, nodeChecked);
                    }
                }
            }

            private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
            {
                // The code only executes if the user caused the checked state to change.
                if (e.Action == TreeViewAction.ByMouse)
                {
                    if (e.Node.Nodes.Count > 0)
                    {
                        // Calls the CheckAllChildNodes method, passing in the current
                        // checked value of the TreeNode whose checked state changed.
                        CheckAllChildNodes(e.Node, e.Node.Checked);
                    }
                }

            }
将此行放入表单加载事件或按钮单击事件中

PopulateFolderTreeView(@"C:\Program Files\", null);

如果您使用数据绑定,那么这可能不是TreeView的问题,而是数据绑定的问题。它不会更新不可见的控件。有关Winforms选项卡控件的问题,请参见此部分。

两件事。第一,您不需要在其中任何一个中使用“if(e.Node.Nodes.Count>0)”。这有点多余,就好像调用“foreach”时有0个节点一样,它会立即从循环中传出

第二,最简单的解决方案可能是直接连接到AfterExpand方法,当节点展开时,设置子节点,然后:

private void FileTreeView_AfterExpandobject sender, TreeViewEventArgs e)
{
    // Calls the CheckAllChildNodes method, passing in the current
    // checked value of the TreeNode whose checked state changed.
    CheckAllChildNodes(e.Node, e.Node.Checked);        
}

另外,您确定要在事件方法中使用TreeViewCancelEventArgs,而不仅仅是TreeViewEventArgs吗?

我认为OP在填充treeview时没有任何问题。您好,谢谢您的建议。我已尝试实现您描述的方法,但当我运行应用程序并尝试执行该行时,我收到以下运行时错误:“UnauthorizedAccessException未经处理”“对路径“C:\Program Files\Common Files\”的访问被拒绝。”我已检查了凭据,它们似乎到处都正常。抱歉,我说的这一行是“string[]directoriesArray=Directory.GetDirectories(directories);”请检查