Question

First off we have the almighty code!

List nodes = new List();
TreeNode Temp = new TreeNode();

TreeNodeCollection nodeList = treeViewTab4DirectoryTree.Nodes;

while (nodeList.Count != 0)
{
    Temp = nodeList[0];

    while (Temp.FirstNode != null)
    {
        Temp = Temp.FirstNode;
    }

    if (!nodes.Contains(Temp.FullPath))
    {
        nodes.Add(Temp.Text);
    }

    nodeList.Remove(Temp);
}

Now the problem: I have written the code above with the intent of creating a List containing the text from all the nodes in the tree. That works perfectly. The problem I am having is when I remove the nodes from my variable they are also being removed from the actual list. The question would be how can I make a copy of the list of nodes so I can play with them without messing with the ACTUAL list. How do I make a copy of it without just making a reference to it? Any help will be greatly appreciated!

Was it helpful?

Solution

Your problem arises because "nodeList" is a reference to treeViewTab4DirectoryTree.Nodes, rather than a copy of it.

The solution depends entirely on the what type of TreeNodeCollection you're using (WinForms, ASP.net, something else?), as you'll need to look for a .Copy(), .Clone(), .ToArray() method or similar to take a copy of the contents of the collection, rather than a reference to the existing collection.

If, for example, you're using asp.net and thus the System.Web.UI.WebControls.TreeNodeCollection, you could use the .CopyTo method in a way similar to this:

TreeNode[] x = null;
treeViewTab4DirectoryTree.Nodes.CopyTo(x, 0);

OTHER TIPS

Updated to show stack based approach:

List<String> result = new List<String>();
Stack<IEnumerator> nodeColls = new Stack<IEnumerator>();
IEnumerator nodes = treeViewTab4DirectoryTree.Nodes.GetEnumerator();

nodeColls.Push(null);

while (nodes != null)
{
    while (nodes.MoveNext())
    {
        result.add(nodes.Current.FullPath);
        if (nodes.Current.FirstNode != null)
        {
            nodeColls.Push(nodes);
            nodes = nodes.Current.Nodes.GetEnumerator();
        }
    }

    nodes = nodeColls.Pop();
}

The code below does not work as was mentioned in comments, because it doesn't traverse the entire tree, but only takes the first leaf node of each top-level branch.

I actually thought the original code (in the question) did so too, because I thought the Remove would actually remove the top-level node after finding the first leaf node under it; but instead, it tries to remove the leaf node from the collection of top-level nodes, and just ignores it if it can't find it.

Original post, non-functioning code

First of all, why do you need to remove the items from your list?

List<string> nodes = new List<string>();

foreach (TreeNode tn in treeViewTab4DirectoryTree.Nodes)
{
    TreeNode temp = tn;

    while (Temp.FirstNode != null)
    {
        Temp = Temp.FirstNode;
    }

    if (!nodes.Contains(Temp.FullPath))
    {
        nodes.Add(Temp.Text);
    }
}

To answer your concrete question, assuming the Nodes collection implements IEnumerable, use:

List<TreeNode> nodeList = new List<TreeNode>(treeViewTab4DirectoryTree.Nodes);

If you do decide to stick with your while loop, you can save an instatiation by changing

TreeNode Temp = new TreeNode();

to

TreeNode Temp = null;

... you're never actually using the object you create, at least in the part of the code you've shown.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top