开发者

Need help understanding .Net Collection behaviour for a TreeNodeCollection

I have a ASP.net page that contains a TreeView that is updated dynamically. I have encountered a problem using the TreeNodeCollection that I can not figure out the reasons behind.

The following code is a much simplified replication of the issue, when the page_load event fires a treeview control is created with a root node, then a function is called that returns a collection of nodes and subnodes. A For Next loops traverses the collection and adds the nodes to the root node. The TreeView control is then added to the page. The example below works as I expected.

  Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim treeView1 As New TreeView
        treeView1.Nodes.Add(New TreeNode)

        Dim nodeCollection As TreeNodeCollection = GetNodes() 

        For nodeIndex = 0 To nodeCollection.Count - 1
            treeView1.Nodes(0).ChildNodes.Add(nodeCollection(nodeIndex))
        Next

        Me.Form.Controls.Add(treeView1)
    End Sub

    Function GetNodes() As TreeNodeCollection
        Dim tnc As New TreeNodeCollection, tn As New TreeNode, sn 开发者_开发技巧As New TreeNode
        For i = 0 To 4
            tn = New TreeNode("Node" & i)
            tn.ChildNodes.Add(New TreeNode("Subnode1"))
            tn.ChildNodes.Add(New TreeNode("Subnode2"))
            tn.ChildNodes.Add(New TreeNode("Subnode3"))
            tnc.Add(tn)
        Next
        Return tnc
    End Function

To replicate the problem I change the line Return tnc in the GetNodes() function with Return tnc(1).ChildNodes

The function still returns a valid TreeNodeCollection of the three sub nodes that were initially added to Node1.

Now when the codes begins to traverse the collection, in the For Next loop each time a node is added to treeView1 control it is removed from the nodeCollection??? This subsequently messes up for next loop and an Index was out of range error is thrown.

Why after the code change are nodes moved from the collection, when in the initial example the nodeCollection retains all its items.

EDIT

If I change the For Next loop to a For Each loop then the exception is slightly different e.g

For Each thisNode AS TreeNode In nodeCollection
    treeView1.Nodes(0).ChildNodes.Add(thisNode)
Next

generates the exception

Collection was modified; enumeration operation may not execute.

Which kind of makes sense as the current node (for whatever reason) is being moved from the source collection to the treeview. But why doesn't this happen when Return tnc is used?


A TreeNode can belong to only one parent TreeView or parent TreeNode at a given point in time. When you take a TreeNode that belongs to one "tree" and add it to another "tree", it will automatically be removed from its previous owner.

So then why the different between returning the outer node collection as opposed to the child node's sub-collection? I believe this difference is caused because the outer collection has no owner, so it has no owner from which it can be removed. In the case of the child node's sub-collection they all belong to the parent node, so their relationship is able to be tracked.

Here's a little diagram to show the difference:

TreeNodeCollection
    Node 1 (owner=<none>)
        TreeNodeCollection
            Node 1.1 (owner=Node 1)
            Node 1.2 (owner=Node 1)
            Node 1.3 (owner=Node 1)
            Node 1.4 (owner=Node 1)
    Node 2 (owner=<none>)
    Node 3 (owner=<none>)
    Node 4 (owner=<none>)

So this issue would only happen with nodes that have owners.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜