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

发布于 11-15 16:30 字数 1824 浏览 3 评论 0原文

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

以下代码是该问题的简化复制,当 page_load 事件触发时,使用根节点创建树视图控件,然后调用一个函数来返回节点和子节点的集合。 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

为了重现该问题,我将 GetNodes() 函数中的行 Return tnc 更改为 Return tnc(1).ChildNodes

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

现在,当代码开始遍历集合时,在 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 时不会发生这种情况呢?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

初吻给了烟2024-11-22 16:30:03

在给定时间点,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>)

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文