将所有选定(已检查)TreeNodes从一个树视图复制到另一个树视图(包括未经检查的父项)C#

时间:2013-03-19 13:07:47

标签: c# recursion treeview treenode

我在左侧创建了一个目录和文件浏览器TreeView。我希望用户能够浏览树并检查他们想要移动到另一个树视图的文件和目录。

另一个TreeView是我在网上找到的一个名为TreeViewColumn的用户控件。我将使用该控件允许用户将其他数据(类别,属性)添加到所选的文件和文件夹中。

我遇到的麻烦是双重的,我需要递归添加所有孩子(我可以解决这个问题)但我需要将未经检查的父母添加到已检查的孩子(以保留层次结构)。

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

任何人都可以帮助这个代码,以便递归地添加已检查的节点(及其父节点,无论检查状态如何)。我需要维护目录层次结构。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

一个相当(不那么干净,不是首选)的解决方案可能是首先克隆树,然后删除未经检查的分支。

否则,当您添加节点时,请编写递归方法以遍历节点的父节点,直到您到达根节点。只需通过检查childNode.parent是否已存在来优化它,只需忽略分支并继续。即回溯到根节点。

答案 1 :(得分:0)

我得到了它的工作。我已经知道@Yahya在说什么,我希望有一种更简单的方法/更好的方法。

下面的代码当然不是最佳的,我会继续改进它,但此时它正在查看左侧的树视图并将所有已检查的项目(及其父项 - 无论CheckedState)复制到右边的树视图。

希望这有助于某人并感谢您回答@Yahya。 我愿意接受改进,但请记住,这是一次性使用实用程序。

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

    }