Необработанное исключение типа «System.StackOverflowException» произошло в mscorlib.dll - PullRequest
1 голос
/ 20 июля 2009

У меня есть подпрограмма ниже, которая проверяет все дочерние узлы узла в форме дерева Windows, когда проверяется узел. Я получаю сообщение об ошибке, указанное в теме, каждый раз, когда щелкаю по нему, но это происходит только в том случае, если в настройках выбрано свойство. Если я просто запускаю закомментированную строку 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 ]

8 голосов
/ 20 июля 2009

Происходит то, что в событии AfterCheck вы 'проверяете' узел дерева, который запускает событие AfterCheck, в котором вы 'проверяете' узел, который запускает событие AfterCheck, в котором вы 'проверяете' узел , который запускает событие AfterCheck, в котором вы «проверяете» узел, который запускает событие AfterCheck, в котором вы «проверяете» узел, который запускает событие AfterCheck, в котором вы «проверяете» узел, который запускает AfterCheck событие, в котором вы «проверяете» узел, который запускает событие AfterCheck, в котором вы «проверяете» узел, который запускает событие AfterCheck, в котором вы «проверяете» узел, который запускает событие AfterCheck, в котором вы «Проверить» узел, который запускает событие AfterCheck, в котором вы «проверяете» узел, который запускает событие AfterCheck, в котором вы «проверяете» узел, который запускает событие AfterCheck, в котором вы «проверяете» узел , который запускает событие AfterCheck, в котором вы 'проверяете' узел, что вызывает переполнение стека.

Чтобы исправить, не устанавливайте Checked в обработчике событий AfterCheck.

6 голосов
/ 20 июля 2009

Документация для события TreeView.AfterCheck гласит:

Настройка TreeNode.Checked собственность из BeforeCheck или AfterCheck причины обработчика событий событие, которое будет вызвано несколько раз и может привести к неожиданному поведению. Чтобы предотвратить событие было поднято несколько раз, добавьте логику к вашему обработчик событий, который выполняет только рекурсивный код, если Action свойство TreeViewEventArgs является не установлено на TreeViewAction.Unknown.

Событие вызывается при каждом вызове s.Nodes (i). Проверено.

1 голос
/ 20 июля 2009

Эта строка:

s.Nodes(i).Checked = True

заставляет само событие TreeView1_AfterCheck запускаться.Так что это бесконечный цикл.

Вам нужно переписать код более тщательно, чтобы вы не переназначали Checked = True, если Checked уже истина, и, возможно, используйте закрытое поле для проверкипосмотрите, выполняется ли текущее событие при входе.

0 голосов
/ 20 июля 2009

Вместо перебора всех корневых узлов 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

EDIT:

Вам не нужно проверять e.Action здесь, и действительно не следует, по 2 причинам:

  • Поскольку вы перечисляете дочерние элементы проверенного узла, у вас не будет проблем с бесконечной рекурсией, которая была у вас в исходном коде.
  • Если вы выйдете, когда e.Action = unknown, тогда, если у вас есть 3 уровня в древовидной структуре, он выберет только непосредственных потомков выбранного узла, а не всех потомков.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...