0

I am trying to build a treeview recursively using VB.Net this is my code so far

.... Code to get the data table 

For Each row As DataRow In dt.Rows

        Dim oName As String = Nothing
        Dim pId As String = Nothing
        Dim cId As String = Nothing
        Dim cmts As String = Nothing
        Dim lvl As String = Nothing
        oName = row(0)
        pId = row(4)
        cId = row(5)
        If Not String.IsNullOrEmpty(row(3).ToString()) Then
            cmts = row(3)
        End If
        lvl = row(2)

        list.Add(New MyObject() With { _
                                    .ObjectName = oName,
                                    .ParentId = pId,
                                    .ChildId = cId,
                                    .Comments = cmts,
                                    .level = lvl
                                })

    Next

BindTree(list, Nothing)

End Sub



Private Sub BindTree(list As IEnumerable(Of MyObject), parentNode As TreeNode)
    Dim nodes = list.Where(Function(x) If(parentNode Is Nothing, x.ParentId = "[Transform].[(Root)]", x.ParentId = parentNode.Value))
    For Each node As MyObject In nodes
        Dim newNode As New TreeNode(node.ObjectName, node.ParentId.ToString())
        If parentNode Is Nothing Then
            TreeView1.Nodes.Add(newNode)
        Else
            parentNode.ChildNodes.Add(newNode)
        End If
        BindTree(list, newNode)
    Next
End Sub

also the new class

Public Class MyObject
Public ObjectName As String
Public ParentId As String
Public ChildId As String
Public Comments As String
Public level As Integer
End Class

The issue I am having is that when this goes so far through the recursion I get a System.StackOverFlowException. When looking at the exception snapshot every thing says "unable to evaluate expression" The error is coming from this line

Dim nodes = list.Where(Function(x) If(parentNode Is Nothing, x.ParentId = "[Transform].[(Root)]", x.ParentId = parentNode.Value)) but Ive no idea why or how to resolve it.

Any help would be very much appreciated.

Thanks

Simon

4
  • Try to call BindTree(list, newNode) inside else block. Commented Nov 18, 2015 at 16:58
  • @JorgeCalvoMorales the BindTree(list, newNode) is called regardless of being in or out of the else as its outside the if statement. Commented Nov 18, 2015 at 18:42
  • You must have a terminating condition where the method can return, usually if a node doesn't have child nodes, thus the recursion can be completed and won't fall to a no-infinity loop. That's why I suggested you move your call to the else block. You shouldn't call every time your recursive method, it must return. Commented Nov 18, 2015 at 20:26
  • @JorgeCalvoMorales I kind of see what you mean, but am so full of flu I cannot think correctly at the moment. Commented Nov 19, 2015 at 8:52

1 Answer 1

2

A StackOverflowException isn't thrown by a particular line of code, that's just the first line of code in the method being called which is overflowing the stack. And there isn't any more information that can really be given, because no further code can be executed. (Because the stack is full.)

Your method is recursive:

Private Sub BindTree(list As IEnumerable(Of MyObject), parentNode As TreeNode)
    ' ...
    BindTree(list, newNode)
End Sub

Which is ok, except that you're not modifying the list variable anywhere. So every time you call the method, you call it with the same list. Therefore it will continue to perform the same logic, recursively, indefinitely, with no terminating condition.

Generally, you should think of a recursive method with the following structure (in VB-ish pseudo-code):

Method(ByVal something As SomeType)
    ' Check if the recursion should end
    If SomeTerminatingCondition Then
        Return
    End If

    ' Perform the logic for this step of the recursion
    DoSomething()

    ' Recurse again
    Method(somethingModified)
End Method

It's not entirely clear to me from the code how list should be modified. But presumably when you call BindTree(list, newNode) at that point list should be some subset of the original list.

Sign up to request clarification or add additional context in comments.

7 Comments

The list isnt being modified, I am trying to iterate through the list of and create a treeview
@SimonPrice: Yes, that's my point. If you want to do this recursively then each iteration of the recursion needs to be given a subset or some modified version of the previous iteration. Otherwise what will cause the recursion to terminate?
ok, ive not worked with recursion much in the past, how would be best to modify my code to acheive this?
@SimonPrice: This is where debugging is really going to give you the answer you're looking for. Step through the code as it executes and examine the runtime values and behavior of each iteration of the recursive function. It's possible that you don't want to modify list itself, but you do want to have some kind of terminating condition in the function. The core of the problem is that you have an infinite recursion. You need to find some logic by which it would know when to stop. (In this case, to know when it has traversed the entire tree.)
@SimonPrice: Maybe you have bad data? Do any of your nodes create an infinite loop with one another? (Something like, A is parent of B, which is parent of C, which is parent of A?)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.