Copy all treeView parent and children to another treeView c# WinForms
Asked Answered
H

5

13

I am trying to copy the entire tree (exactly all nodes) of a treeview (completely) to another treeview using this code:

        TreeNodeCollection myTreeNodeCollection = treeView1.Nodes;

        TreeNode[] myTreeNodeArray = new TreeNode[treeView1.Nodes.Count];

        treeView1.Nodes.CopyTo(myTreeNodeArray, 0);

        treeView2.Nodes.AddRange(myTreeNodeArray);

But this does not allow me to do so, it asks to either delete the nodes in source treeview or use it Clone! How can I do that? I dont want my source treeview to lose anything in this process.

** UPDATE ** Ok guys I found a complicated code (for me!!) but how can I use this?

    public static T DeepTreeCopy<T>(T obj)
    {
        object result = null;
        using (var ms = new MemoryStream())
        {
            var formatter = new BinaryFormatter();
            formatter.Serialize(ms, obj);
            ms.Position = 0;
            result = (T)formatter.Deserialize(ms); ms.Close();
        }
        return (T)result;
    } 
Hyperactive answered 11/4, 2011 at 10:8 Comment(2)
In the first code, one needs to remove the nodes from the TreeView1,Nodes collection before adding them to other collection: foreach (TreeNode node in treeView1.Nodes) { treeView1.Nodes.Remove(node); } This should be faster and cleaner than cloning.Incisive
I think the Clone() answer by @jeffjohnson should be marked as the accepted answer.Zulemazullo
S
13

try this

public void Copy(TreeView treeview1, TreeView treeview2)
{
    TreeNode newTn;
    foreach (TreeNode tn in treeview1.Nodes)
    {
        newTn = new TreeNode(tn.Text, tn.Value);
        CopyChilds(newTn, tn);
        treeview2.Nodes.Add(newTn);
    }
}

public void CopyChilds(TreeNode parent, TreeNode willCopied)
{
    TreeNode newTn;
    foreach (TreeNode tn in willCopied.ChildNodes)
    {
        newTn = new TreeNode(tn.Text, tn.Value);
        parent.ChildNodes.Add(newTn);
    }
} 

My regards

Severen answered 11/4, 2011 at 10:41 Comment(3)
Thanks, it has same problem of (node should be deleted before copy or should be Cloned)Hyperactive
you forgot calling CopyChild() method in itself !Franglais
You should can use the Clone method. It will clone the entire subtree.Mauldon
D
10

Like MohD's answer, but with recursion to get all nodes. (Nodes of childnodes)

    public void CopyTreeNodes(TreeView treeview1, TreeView treeview2)
    {
        TreeNode newTn;
        foreach (TreeNode tn in treeview1.Nodes)
        {
            newTn = new TreeNode(tn.Text, tn.ImageIndex, tn.SelectedImageIndex);
            CopyChildren(newTn, tn);
            treeview2.Nodes.Add(newTn);
        }
    }
    public void CopyChildren(TreeNode parent, TreeNode original)
    {
        TreeNode newTn;
        foreach (TreeNode tn in original.Nodes)
        {
            newTn = new TreeNode(tn.Text, tn.ImageIndex, tn.SelectedImageIndex);
            parent.Nodes.Add(newTn);
            CopyChildren(newTn, tn);
        }
    } 
Dulcinea answered 15/9, 2014 at 17:26 Comment(1)
Cloning will be a little bit complicated if you derive from the TreeNode (maybe not a greatest idea).Incisive
M
9

Using the node.Clone() function works as well...

foreach (TreeNode node in treeViewSource.Nodes)
{
    treeViewTarget.Nodes.Add((TreeNode)node.Clone());
}

Adding a root node will help ensure the "PlusMinus" functionality is viewable.

TreeNode rootNode = new TreeNode("Root Node");
treeViewTarget.Nodes.Add(rootNode);
foreach (TreeNode node in treeViewSource.Nodes)
{
    rootNode.Nodes.Add((TreeNode)node.Clone());
}
rootNode.Expand();
Mlle answered 17/6, 2012 at 16:33 Comment(4)
'Clone performs only a "shallow copy:" so any child nodes of the nodes being copied will not be copied to the new TreeView.Ragamuffin
@BillW. I believe MSDN says it will clone the entire subtree. msdn.microsoft.com/en-us/library/…Mauldon
I just tested it and it does indeed clone the entire subtree.Superload
@surasb note that the "shallow copy" aspect comes into play when the Tag value of a TreeNode is a reference Type: MSDN article cited: "The Clone method performs a shallow copy of the node. If the value of the Tag property is a reference type, both the original and cloned copy will point to the same single instance of the Tag value."Ragamuffin
B
0

Thank you guys for the Answers. Combining all answers this worked for me. Even if the treeview has multiple levels.

  public void CopyTreeNodes(TreeView treeview1, TreeView treeview2)
    {
        TreeNode newTn;
        foreach (TreeNode tn in treeview1.Nodes)
        {
            newTn = new TreeNode(tn.Text, tn.Value);
            CopyChildren(newTn, tn);
            treeview2.Nodes.Add(newTn);
        }
    }

 public void CopyChildren(TreeNode parent, TreeNode original)
    {
        TreeNode newTn;
        foreach (TreeNode tn in original.ChildNodes)
        {
            newTn = new TreeNode(tn.Text, tn.Value);
            parent.ChildNodes.Add(newTn);
            CopyChildren(newTn, tn);
        }
    }
Beauregard answered 18/11, 2021 at 2:25 Comment(0)
A
-1

You can use this at the desired level

     public void RootCopy(TreeView treeview1, TreeView treeview2)
    {
        TreeNode newNode;
        foreach (TreeNode tnode in treeview1.Nodes)
        {
            newNode = new TreeNode(tnode.Text);
            treeview2.Nodes.Add(newNode);
            if (tnode.Nodes.Count != 0)
            {
                int _1index = tnode.Index;
                ChildsCopyLevel2(_1index, treeview1, treeview2);
            }


        }

    }


    public void ChildsCopyLevel2(int index1, TreeView TV1, TreeView TV2)
    {
        foreach (TreeNode Tnode in TV1.Nodes[index1].Nodes)
        {
            string Childtext = Tnode.Text;
            TV2.Nodes[index1].Nodes.Add(Childtext);
            if (Tnode.Nodes.Count != 0)
            {// ChildsCopyLevel3(Tnode.Nodes.Count, TV1, TV2);
                int _2index = Tnode.Index;
                ChildsCopyLevel3(index1, _2index, TV1, TV2);
            }
        }

    }


    public void ChildsCopyLevel3(int index1, int index2, TreeView TV1, TreeView TV2)
    {
        foreach (TreeNode Tnode in TV1.Nodes[index1].Nodes[index2].Nodes)
        {
            string Childtext = Tnode.Text;
            TV2.Nodes[index1].Nodes[index2].Nodes.Add(Childtext);
        }
    }
Amund answered 4/2, 2017 at 6:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.