开发者

C# tree is duplicating every node when I add to it

So basically what I am doing is building a tree backwards. I am starting at the leaves, then adding their parents, then theirs (it is a 3 level tree in the end).

I have no problem adding the leaves (I query a database, and for each entry create a TNode (extension of the TreeNode Class), and then add them to the tree). There is no duplicatio开发者_Go百科n in this step - the duplication happens when I go to add the leaves' parents.

I loop through the tree of leaves, and pretty much make a new parent node when two leaves have different Section Numbers (Just a number that I want to group by).

What the program is doing is creating TWO SETS of each leaf node UNDER EACH PARENT, so it looks like this:

it wont let me post an image, so I will try to draw the tree in text: something like this

    Part 1
       child 1-1
       child 1-2
       child 1-3
       child 1-1
       child 1-2
       child 1-3
    Part 2
       child 2-1
       child 2-2       
       child 2-1
       child 2-2  

Here is the code that is doing it...It is really wierd, cause when I debug it, the number of children of each node grows by ONE each time as expected, but then once all the parent nodes are added, there is two of each leaf...

I have also tried cutting count down to be just 1, and it adds ONE parent, and it has ONE child, which is duplicated....

Anyways, Code:

Note the switch statements arent really important, they just set the text of the new node

private void addLvl1Nodes() {

    int i = 0;
    TNode newNode = null;
    int count = tv_master.Nodes.Count;
    while (i < count) {
        TNode tn = (TNode)tv_master.Nodes[i];//get current node
            //if i = 0, then newNode has not been set, so make a new one!
            if ((i == 0)||
                (tn.Section != ((TNode)tv_master.Nodes[i-1]).Section )||
                (tn.Text.Substring(0, 1) != tv_master.Nodes[i - 1].Text.Substring(0, 1))){

                newNode = new TNode("");
                tv_master.Nodes.Add(newNode);
                switch (tn.Text.Substring(0, 1)) {
                    case "1": newNode.Text = "Part One"; break;
                    case "2": newNode.Text = "Part Two"; break;
                    case "3": newNode.Text = "Part Three"; break;
                }

                newNode.Section = tn.Section;

            }
        newNode.Nodes.Add(tn);

        i++;
    }
}

Hopefully someone has had a similar error before - because I just cannot find the solution.

Thanks a lot!

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

For anyone who runs into a similar issue, here is the final copy of my code, working as expected now :)

private void addLvl1Nodes() {

            TNode newNode = null;

            List<TNode> nodes = tv_master.Nodes.Cast<TNode>().ToList();
            tv_master.Nodes.Clear();

            for(int i = 0; i<nodes.Count; i++){
                TNode tn = nodes[i];

                if ((i == 0) ||
                    (tn.Section != nodes[i-1].Section) ||
                    (tn.Text[0] != nodes[i-1].Text[0])) {

                    newNode = new TNode("");
                    tv_master.Nodes.Add(newNode);
                    switch (tn.Text[0]) {
                        case '1': newNode.Text = "Part One"; break;
                        case '2': newNode.Text = "Part Two"; break;
                        case '3': newNode.Text = "Part Three"; break;
                    }

                    newNode.Section = tn.Section;

                }

                newNode.Nodes.Add(tn);

            }
        }


It looks like you might need to remove tn from it's old parent before making this call:

  newNode.Nodes.Add(tn);

Otherwise, you won't actually have two seperate instances of tn (the child node), but it'll show up more than once in the hierarchy. (Once under tv_master directly, once under the newly created node.)

It might make some sense to just keep two separate lists (or trees) of nodes. One to hold the newly created parent nodes, and one for the leaf nodes. Then you can join everything up at the end. Maybe start your loop like this:

List<TNode> listLeafNodes = new List<TNode>(tv_master.Nodes);
tv_master.Nodes.Clear();
for( int i=0; i<listLeafNodes.Count; ++i )
{
...
}

Of course, I'm not sure what class you're using for TNode and tv_master. The TNode interface I saw on MSDN didn't seem to have any .Nodes attribute. Also there appear to be at least 3 different TreeView classes. Fully qualified class names for TNode and the definition of tv_master might help us understand things better.


As ebyrob already explained, you are adding the same node to the tree twice, so clearing the initial list of nodes at the beginning will help.

To add to their answer, the reason why your initial nodes also get "moved" outside of the root is that TreeNodeCollection.Add method not only adds the node to its internal array, but also changes the node's private parent field to point to its new parent.

That way each of the initial nodes becomes referenced from two places in your tree (root and 1st child node), but its Parent property makes both references get rendered under its parent node.


This may not seem a real solution, but it could help you nonetheless. By analyzing your provided code I encountered, that you use the same node collection to get your child elements from as well as append your new nodes. But the child elements are never removed from the original nodes collection. So basically you have the child nodes as well as the new nodes for the sections in the same collection.

You should remove the child elements from the collection, that already have been processed. But beware, that in doing so your expression in the while loop has to change.

Furthermore you could simplify the following line

tn.Text.Substring(0, 1)

like this

tn.Text[0]

This goes also for the comparison of the first characters later in the code sample.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜