mscorlib.dll中发生了未处理的“System.StackOverflowException”类型异常

时间:2009-07-20 15:57:55

标签: .net winforms treeview

我有以下sub,它在检查节点时检查Windows窗体树视图中的所有节点的子节点。每当我点击它时,我都会收到主题中所述的错误,但这只会在设置checked属性时发生。如果我只运行注释掉的MsgBox行,它可以正常工作而没有错误。

Private Sub TreeView1_AfterCheck(ByVal sender As System.Object, ByVal e As _
    TreeViewEventArgs) Handles TreeView1.AfterCheck
    For Each s As TreeNode In TreeView1.Nodes
        If s.Checked = True Then
            For i As Integer = 0 To s.Nodes.Count - 1
                MsgBox(s.Nodes(i).Text)
                s.Nodes(i).Checked = True
            Next
        End If
    Next
End Sub

由于这是一个StackOverflow例外,这似乎是最好的地方询问它!

4 个答案:

答案 0 :(得分:8)

在AfterCheck事件中,您正在“检查”一个树节点,该节点将触发AfterCheck事件,在该节点中您“检查”一个节点,该节点将触发AfterCheck事件,在该事件中您“检查”一个节点,它会激活AfterCheck事件,在其中“检查”一个节点,该节点触发AfterCheck事件,在该节点中“检查”一个节点,该节点触发AfterCheck事件,在该事件中“检查”一个节点,该节点触发AfterCheck事件,在其中“检查”一个节点,该节点触发AfterCheck事件,在该节点中,您“检查”一个节点,该节点将触发AfterCheck事件,在该事件中,您“检查”一个节点,该节点将触发AfterCheck事件, “检查”一个节点,该节点触发AfterCheck事件,在该节点中“检查”一个节点,该节点触发AfterCheck事件,在该节点中“检查”一个节点,该节点触发AfterCheck事件,在该节点中“检查”节点,它会触发AfterCheck事件,在该事件中,您'检查'一个节点,这会导致堆栈溢出。

要修复,请不要在AfterCheck事件处理程序中设置Checked。

答案 1 :(得分:6)

TreeView.AfterCheck事件的文档说:

  

设置TreeNode.Checked   BeforeCheck内的财产   或AfterCheck事件处理程序原因   要多次举起的活动   并可能导致意外的行为。   防止事件被提升   多次,为您添加逻辑   只执行你的事件处理程序   Action的递归代码   TreeViewEventArgs的属性是   未设置为TreeViewAction.Unknown

每次调用s.Nodes(i)时都会引发事件。检查。

答案 2 :(得分:1)

这一行:

s.Nodes(i).Checked = True

导致事件TreeView1_AfterCheck自行触发。所以这是一个无限循环。

您需要更仔细地重写代码,以便在Checked = True已经为真的情况下不重新分配Checked,并且可能使用私有字段来检查当前事件已经进入。

答案 3 :(得分:0)

您可以简单地遍历引发事件的已检查节点的子节点,而不是遍历TreeView的所有根节点:

Private Sub TreeView1_AfterCheck(ByVal sender As System.Object, ByVal e As TreeViewEventArgs) Handles TreeView1.AfterCheck
    If e.Node.Checked Then
        For Each child As TreeNode In e.Node.Nodes
            child.Checked = True
        Next
    End If
End Sub

修改

您无需在此检查e.Action,实际上也不应该,原因有两个:

  • 当您枚举已检查节点的子节点时,您将不会遇到原始代码中无限递归的问题。
  • 如果在e.Action = unknown时退出,那么如果树视图中有3个级别,它将只选择所选节点的直接子级,而不是所有后代。