需要帮助了解TreeNodeCollection的.Net Collection行为

时间:2011-06-15 12:57:29

标签: .net asp.net collections treeview nodes

我有一个ASP.net页面,其中包含一个动态更新的TreeView。我使用TreeNodeCollection遇到了一个问题,我无法弄清楚背后的原因。

以下代码是对问题的简化复制,当page_load事件触发使用根节点创建树视图控件时,则调用返回节点和子节点集合的函数。 A For Next循环遍历集合并将节点添加到根节点。然后将TreeView控件添加到页面中。以下示例按预期工作。

  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

要复制问题,我使用Return tnc更改了GetNodes()函数中的行Return tnc(1).ChildNodes

该函数仍然返回最初添加到Node1的三个子节点的有效TreeNodeCollection。

现在当代码开始遍历集合时,在For Next循环中每次将一个节点添加到treeView1控件时,它都会从nodeCollection中删除???这随后混淆了下一个循环并且索引超出了范围错误。

为什么代码更改后是从集合中移出的节点,在初始示例中,nodeCollection会保留其所有项目。

修改

如果我将For Next循环更改为For Each循环,则异常略有不同,例如

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

生成异常

  

收藏被修改;枚举操作可能无法执行。

当前节点(无论出于何种原因)从源集合移动到树视图时,哪种有意义。但是为什么在使用Return tnc时不会发生这种情况?

1 个答案:

答案 0 :(得分:2)

TreeNode在给定时间点只能属于一个父TreeView或父TreeNode。当您使用属于一个“树”的TreeNode并将其添加到另一个“树”时,它将自动从其之前的所有者中删除。

那么为什么返回外部节点集合而不是子节点的子集合之间的区别呢?我认为这种差异是因为外部集合没有所有者,因此没有所有者可以从中删除。对于子节点的子集合,它们都属于父节点,因此可以跟踪它们之间的关系。

这是一个显示差异的小图:

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

所以这个问题只会发生在拥有所有者的节点上。