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

时间:2012-06-17 23:07:36

标签: c# winforms treeview checkbox

我是新来的,几乎无处不在寻找我的问题的答案 - 无济于事。我希望这里有人可以提供帮助。

我有一个WinForm应用程序,我使用TreeView在选定的根文件夹下显示文件夹结构。树视图启用了CheckBoxes。当我选中或取消选中TreeNode上的复选框时,TreeNode下面的任何可见节点也会发生变化 - 到目前为止一切都很好。

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

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

    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);
            }
        }
    }

似乎递归函数只关心在执行时可见的TreeNodes。

如果有人能够提供有关错误的线索,以及可以采取哪些措施来纠正错误,我们将不胜感激。

提前致谢。

致以最诚挚的问候,

升。 Hummel公司

3 个答案:

答案 0 :(得分:2)

两件事。一,你不需要“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吗?

答案 1 :(得分:1)

如果您使用数据绑定,那么它可能不是TreeView问题,这是数据绑定的问题。它不会更新不可见的控件。有关Winforms Tabcontrol问题,请参阅此MSDN thread

答案 2 :(得分:-1)

我试图复制您在代码中可能正在做的事情,请您使用此代码并确认它是否正常工作或您遇到同样的问题。

 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);
                    }
                }

            }

将此行放在Form Load事件或Button Click事件

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