fs25053
asked on
Bad Performance with Recursive Treeview Functions
Hi,
I’ve written some recursive treeview browsing functions. The sample below shows a function, which only searches and highlights a node.
But the performance is very, very bad. My Treeview has about 2000 nodes. Any suggestions?
Many thanks
Dominic Birrer
Here are the two subs (first the initial sub, then the recursive sub):
'*** Loop sub through all rootnodes
Public Sub SearchWAs(ByRef MyTrv As firstTreeView.Cls_firstTre eView, ByVal PK_WA As Integer)
Dim RootNode As New firstTreeView.Cls_firstTre eNode()
'*** Loop sub through all rootnodes
For Each RootNode In MyTrv.Nodes
'*** if node found
If RootNode.PK = PK_WA And RootNode.Key1 = "WA" Then
RootNode.Expand()
RootNode.Key5 = "1"
RootNode.BackColor = Color.Tomato
End If
'*** start the recursive sub
SearchWAs_Rec(RootNode, PK_WA)
Next
End Sub
'*** recursive Loop sub through all childnodes
Public Sub SearchWAs_Rec(ByVal ParentNode As firstTreeView.Cls_firstTre eNode, ByVal PK_WA As Integer)
Dim ChildNode As New firstTreeView.Cls_firstTre eNode()
'*** recursive Loop sub through all childnodes
For Each ChildNode In ParentNode.Nodes
'*** if node found
If ChildNode.PK = PK_WA And ChildNode.Key1 = "WA" Then
ChildNode.BackColor = Color.Tomato
ChildNode.Key5 = "1"
'*** starts an other recursive sub to expand all nodes from the actual node up to the root node (this sub is build similar)
ExpandParentNodes_Rec(Chil dNode)
End If
'*** start itself with actual node as parentnode
SearchWAs_Rec(ChildNode, PK_WA)
Next
End Sub
I’ve written some recursive treeview browsing functions. The sample below shows a function, which only searches and highlights a node.
But the performance is very, very bad. My Treeview has about 2000 nodes. Any suggestions?
Many thanks
Dominic Birrer
Here are the two subs (first the initial sub, then the recursive sub):
'*** Loop sub through all rootnodes
Public Sub SearchWAs(ByRef MyTrv As firstTreeView.Cls_firstTre
Dim RootNode As New firstTreeView.Cls_firstTre
'*** Loop sub through all rootnodes
For Each RootNode In MyTrv.Nodes
'*** if node found
If RootNode.PK = PK_WA And RootNode.Key1 = "WA" Then
RootNode.Expand()
RootNode.Key5 = "1"
RootNode.BackColor = Color.Tomato
End If
'*** start the recursive sub
SearchWAs_Rec(RootNode, PK_WA)
Next
End Sub
'*** recursive Loop sub through all childnodes
Public Sub SearchWAs_Rec(ByVal ParentNode As firstTreeView.Cls_firstTre
Dim ChildNode As New firstTreeView.Cls_firstTre
'*** recursive Loop sub through all childnodes
For Each ChildNode In ParentNode.Nodes
'*** if node found
If ChildNode.PK = PK_WA And ChildNode.Key1 = "WA" Then
ChildNode.BackColor = Color.Tomato
ChildNode.Key5 = "1"
'*** starts an other recursive sub to expand all nodes from the actual node up to the root node (this sub is build similar)
ExpandParentNodes_Rec(Chil
End If
'*** start itself with actual node as parentnode
SearchWAs_Rec(ChildNode, PK_WA)
Next
End Sub
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Many thanks ! This works very well!! Extremely increased performance...yeeeehaaaw..
Cheers,
Dominic
BTW - Here's the VB.Net Translation (if somebody else has the same problem):
Public Sub SearchWAs(ByRef MyTrv As firstTreeView.Cls_firstTre eView, ByVal PK_WA As Integer)
Dim myEnumerator As IEnumerator = MyTrv.Nodes.GetEnumerator
ClearNodeSettings(MyTrv)
While (myEnumerator.MoveNext())
Dim RootNode As firstTreeView.Cls_firstTre eNode = CType(myEnumerator.Current , firstTreeView.Cls_firstTre eNode)
If RootNode.PK = PK_WA And RootNode.Key1 = "WA" Then
RootNode.Expand()
RootNode.Key5 = "1"
RootNode.BackColor = Color.Tomato
End If
SearchWAs_Rec(RootNode, PK_WA)
End While
End Sub
Public Sub SearchWAs_Rec(ByVal ParentNode As firstTreeView.Cls_firstTre eNode, ByVal PK_WA As Integer)
Dim myEnumerator As IEnumerator = ParentNode.Nodes.GetEnumer ator
While (myEnumerator.MoveNext())
Dim ChildNode As firstTreeView.Cls_firstTre eNode = CType(myEnumerator.Current , firstTreeView.Cls_firstTre eNode)
If ChildNode.PK = PK_WA And ChildNode.Key1 = "WA" Then
ChildNode.BackColor = Color.Tomato
ChildNode.Key5 = "1"
ExpandParentNodes_Rec(Chil dNode)
End If
SearchWAs_Rec(ChildNode, PK_WA)
End While
End Sub
Cheers,
Dominic
BTW - Here's the VB.Net Translation (if somebody else has the same problem):
Public Sub SearchWAs(ByRef MyTrv As firstTreeView.Cls_firstTre
Dim myEnumerator As IEnumerator = MyTrv.Nodes.GetEnumerator
ClearNodeSettings(MyTrv)
While (myEnumerator.MoveNext())
Dim RootNode As firstTreeView.Cls_firstTre
If RootNode.PK = PK_WA And RootNode.Key1 = "WA" Then
RootNode.Expand()
RootNode.Key5 = "1"
RootNode.BackColor = Color.Tomato
End If
SearchWAs_Rec(RootNode, PK_WA)
End While
End Sub
Public Sub SearchWAs_Rec(ByVal ParentNode As firstTreeView.Cls_firstTre
Dim myEnumerator As IEnumerator = ParentNode.Nodes.GetEnumer
While (myEnumerator.MoveNext())
Dim ChildNode As firstTreeView.Cls_firstTre
If ChildNode.PK = PK_WA And ChildNode.Key1 = "WA" Then
ChildNode.BackColor = Color.Tomato
ChildNode.Key5 = "1"
ExpandParentNodes_Rec(Chil
End If
SearchWAs_Rec(ChildNode, PK_WA)
End While
End Sub
I'd still recommend cleaning up the code by combining the enumerator with the code i've written.. it could speed it up more.
Public Sub searchNodes(ByRef n As TreeNodeCollection, ByVal PK_WA As Integer)
Dim myEnumerator As IEnumerator = n.GetEnumerator
While (myEnumerator.MoveNext())
singlenode(CType(myEnumera tor.Curren t, firstTreeView.Cls_firstTre eNode))
End While
End Sub
Public Sub singlenode(ByRef n As firstTreeView.Cls_firstTre eNode, ByVal PK_WA As Integer)
If n.PK = PK_WA And n.Key1 = "WA" Then
n.BackColor = Color.Tomato
n.Key5 = "1"
If Not IsNothing(n.Parent) Then ExpandParentNodes_Rec(n)
End If
searchNodes(n.Nodes)
End Sub
KGreg
Public Sub searchNodes(ByRef n As TreeNodeCollection, ByVal PK_WA As Integer)
Dim myEnumerator As IEnumerator = n.GetEnumerator
While (myEnumerator.MoveNext())
singlenode(CType(myEnumera
End While
End Sub
Public Sub singlenode(ByRef n As firstTreeView.Cls_firstTre
If n.PK = PK_WA And n.Key1 = "WA" Then
n.BackColor = Color.Tomato
n.Key5 = "1"
If Not IsNothing(n.Parent) Then ExpandParentNodes_Rec(n)
End If
searchNodes(n.Nodes)
End Sub
KGreg
Private Sub nodecollection(ByRef nodes As TreeNodeCollection)
If Not nodes Is Nothing Then
Dim n As TreeNode
For Each n In nodes
singlenode(n)
Next
End If
End Sub
Private Sub expandancestors(ByRef n As TreeNode)
n.Expand()
If Not n.Parent Is Nothing Then
expandancestors(n)
End If
End Sub
Private Sub singlenode(ByRef n As TreeNode)
If n.Tag = "WA" Then
n.Expand()
n.BackColor = Color.Tomato
End If
If Not n.Parent Is Nothing Then
' This is a child node expand ancestors
expandancestors(n.Parent)
End If
nodecollection(n.Nodes)
End Sub
KGreg