0

I've created a directory and file browser TreeView on the left side. I want the users to be able to browse the tree and check the files and directories that they would like to move to another treeview.

The other TreeView is a user control I found online called TreeViewColumn. I will be using that control to allow the user to add other data (categories, attributes) to the files and folders selected.

The trouble I'm running into is two-fold, I need to recursively add all children (I can figure this out) but I need to add unchecked parents to checked children (to preserve the hierarchy).

   private void IterateTreeNodes(TreeNode originalNode, TreeNode rootNode)
    {
        //Take the node passed through and loop through all children
        foreach (TreeNode childNode in originalNode.Nodes)
        {
            // Create a new instance of the node, will need to add it to the recursion as a root item 
            // AND if checked it needs to get added to the new TreeView.
            TreeNode newNode = new TreeNode(childNode.Text);
            newNode.Tag = childNode.Tag;
            newNode.Name = childNode.Name;
            newNode.Checked = childNode.Checked;
            if (childNode.Checked)
            {
                // Now we know this is checked, but what if the parent of this item was NOT checked. 
                //We need to head back up the tree to find the first parent that exists in the tree and add the hierarchy.
                if (tvSelectedItems.TreeView.Nodes.ContainsKey(rootNode.Name)) // Means the parent exist?
                {

                    tvSelectedItems.TreeView.SelectedNode = rootNode;
                    tvSelectedItems.TreeView.SelectedNode.Nodes.Add(newNode);
                }
                else
                {
                    AddParents(childNode);

                    // Find the parent(s) and add them to the tree with their CheckState matching the original node's state
                    // When all parents have been added, add the current item.
                }
            }
            IterateTreeNodes(childNode, newNode);
        }

    }

    private TreeNode AddParents(TreeNode node)
    {
        if (node.Parent != null)
        {
            //tvDirectory.Nodes.Find(node.Name, false);
        }
        return null;
    }

Could anyone help with this code so that it recursively adds checked nodes (and their parent, regardless of checked state). I need to maintain directory hierarchy.

Thanks for any help!

JFL
  • 25
  • 1
  • 8

2 Answers2

1

A rather (not-so-clean and not-preferred) solution could be to clone the tree first, and then remove unchecked branches.

Else, when you are adding a node, write a recursive method to traverse through node's parent node until you hit the root. And simply optimize it by checking if childNode.parent already exists, just ignore the branch and move on. i.e. Backtrack to root node.

Yahya
  • 3,386
  • 3
  • 22
  • 40
0

I got it working. I was already aware of what @Yahya was saying, I was hoping for an easier way / better approach.

The code below is certainly not optimal, I will continue improving it on my end but at this point it is looking through a treeview on the left and copying all of the checked items (and their parents - regardless of CheckedState) to a treeview on the right.

Hopefully this helps someone and thanks for answering @Yahya. I'm open to improvements but keep in mind this is a one-time use utility.

 private void cmdMoveRight_Click(object sender, EventArgs e)
    {
        tvSelectedItems.TreeView.Nodes.Clear();
        // Traverse first level Tree Nodes
        foreach (TreeNode originalNode in tvDirectory.Nodes)
        {

            TreeNode newNode = new TreeNode(originalNode.Text);
            newNode.Name = originalNode.Name;
            newNode.Tag = originalNode.Tag;
            newNode.Checked = originalNode.Checked;

            //Only add to the new treeview if the node is checked
            if (originalNode.Checked)
            {
                tvSelectedItems.TreeView.Nodes.Find(originalNode.Parent.Name,true)[0].Nodes.Add(newNode);
            }
            //Start recursion - this will be called for each first level node - there should technically only be 1 "ROOT" node.
            IterateTreeNodes(originalNode, newNode);
        }

    }


    private void IterateTreeNodes(TreeNode originalNode, TreeNode rootNode)
    {
        //Take the node passed through and loop through all children
        foreach (TreeNode childNode in originalNode.Nodes)
        {
            // Create a new instance of the node, will need to add it to the recursion as a root item 
            // AND if checked it needs to get added to the new TreeView.
            TreeNode newNode = new TreeNode(childNode.Text);
            newNode.Tag = childNode.Tag;
            newNode.Name = childNode.Name;
            newNode.Checked = childNode.Checked;
            if (childNode.Checked)
            {
                // Now we know this is checked, but what if the parent of this item was NOT checked. 
                //We need to head back up the tree to find the first parent that exists in the tree and add the hierarchy.
                  TreeNode[] nodestest = tvSelectedItems.TreeView.Nodes.Find(childNode.Parent.Name, true);
                  if (nodestest.Length > 0)
                  {
                      tvSelectedItems.TreeView.Nodes.Find(childNode.Parent.Name,true)[0].Nodes.Add(newNode);
                  }
                  else
                  {
                      AddParents(childNode);// Find the parent(s) and add them to the tree with their CheckState matching the original node's state


                  }
            }
            //recurse
            IterateTreeNodes(childNode, newNode);
        }

    }

    private void AddParents(TreeNode node)
    {

        if (node.Parent != null)// Check if parent is null (would mean we're looking at the root item
        {
            TreeNode[] nodestest = tvSelectedItems.TreeView.Nodes.Find(node.Parent.Name, true);
            if (nodestest.Length > 0)
            {

                TreeNode[] nodes = tvDirectory.Nodes.Find(node.Name, true);
                TreeNode newNode = new TreeNode(nodes[0].Text);
                newNode.Name = nodes[0].Name;
                newNode.Tag = nodes[0].Tag;
                newNode.Checked = nodes[0].Checked;
                tvSelectedItems.TreeView.Nodes[node.Parent.Name].Nodes.Add(newNode);
            }
            else
            {
                AddParents(node.Parent);

                TreeNode newNode = new TreeNode(node.Text);
                newNode.Name = node.Name;
                newNode.Tag = node.Tag;
                newNode.Checked = node.Checked;
                tvSelectedItems.TreeView.Nodes.Find(node.Parent.Name,true)[0].Nodes.Add(newNode);

            }
        }
        else // deal with root node
        {
            TreeNode rootNode = new TreeNode(node.Text);
            rootNode.Name = node.Name;
            rootNode.Tag = node.Tag;
            rootNode.Checked = node.Checked;
            tvSelectedItems.TreeView.Nodes.Add(rootNode);
        }

    }
JFL
  • 25
  • 1
  • 8