3

I am new here, and have searched for answers for my problem practically everywhere - to no avail. I hope that somebody here can help.

I have a WinForm application, where I use a TreeView to display the folder structure below a selected root folder. The treeview has enabled CheckBoxes. When I check or uncheck a checkbox on a TreeNode, any visible nodes below that TreeNode changes as well - so far so good.

The problem is, that when I expand the nodes further, then the new visible nodes are not updated to the correct state.

I used the following recursive routine to perform the update:

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

It is called from this event handler:

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

It seems that the recursive function only cares about TreeNodes that are visible at the time of execution.

If anyone can give a clue of what is wrong, and what can be done to correct it, it will be greatly appreciated.

Thanks in advance.

Best regards,

L. Hummel

L. H.
  • 83
  • 2
  • 9

3 Answers3

2

Two things. One, you don't need the "if (e.Node.Nodes.Count > 0)" in either. That is a little redundant as if there are 0 nodes when you call a "foreach", it immediately passes out of the loop.

Two, the easiest solution may be to just wire into the AfterExpand method, and when the node gets expanded, set the children then:

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

Also, are you sure you want TreeViewCancelEventArgs in your event methods, and not just TreeViewEventArgs?

krillgar
  • 12,596
  • 6
  • 50
  • 86
1

If you use data binding then it's likely not a TreeView problem, it is an issue with data binding. It doesn't update controls that aren't visible. See this MSDN thread for Winforms Tabcontrol issue.

Jacob Seleznev
  • 8,013
  • 3
  • 24
  • 34
-1

I tried to replicate what you might be doing in the code can you please use this code and confirm is it working or you are facing the same problem.

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

            }

put this line either in Form Load event or Button Click event

PopulateFolderTreeView(@"C:\Program Files\", null);
MMK
  • 3,673
  • 1
  • 22
  • 30
  • I don't think the OP has any problems populating the treeview in the first place. – Adam Lear Jun 18 '12 at 01:27
  • Hello, Thank you for your suggestion. I have tried to implement the methods you described, but when I run the application and tries to execute the line I get the following runtime-error: "UnauthorizedAccessException was unhandled" "Access to the path 'C:\Program Files\Common Files\' is denied." I've checked the credentials, and they seem ok everywhere. – L. H. Jun 18 '12 at 09:18
  • Sorry, the line I am talking about is the line "string[] directoriesArray = Directory.GetDirectories(directories);" – L. H. Jun 18 '12 at 09:19
  • Please check http://stackoverflow.com/questions/4986293/access-to-the-path-is-denied-when-using-directory-getfiles – MMK Jun 18 '12 at 09:36