How to: Iterate Through All Nodes of a Windows Forms TreeView Control
It is sometimes useful to examine every node in a Windows Forms TreeView control in order to perform some calculation on the node values. This operation can be done using a recursive method (recursive procedure in VB.NET) that iterates through each node in each collection of the tree.
Each TreeNode object in a tree view has properties that you can use to navigate the tree view: FirstNode, LastNode, NextNode, PrevNode, and Parent. The value of the Parent property is the parent node of the current node. The child nodes of the current node, if there are any, are listed in its Nodes property. The TreeView control itself has the TopNode property, which is the root node of the entire tree view.
Recursive approach
The recursive approach uses a method that processes a tree node, and then calls the same method for each child node. This repeats until every node in the tree is processed. The drawback to this approach is that if the tree is big, you may run into a stack overflow error and run out of memory.
The following example shows how to print each TreeNode object's Text property:
private void PrintRecursive(TreeNode treeNode)
{
// Print the node.
System.Diagnostics.Debug.WriteLine(treeNode.Text);
MessageBox.Show(treeNode.Text);
// Visit each node recursively.
foreach (TreeNode tn in treeNode.Nodes)
{
PrintRecursive(tn);
}
}
// Call the procedure using the TreeView.
private void CallRecursive(TreeView treeView)
{
// Print each node recursively.
foreach (TreeNode n in treeView.Nodes)
{
//recursiveTotalNodes++;
PrintRecursive(n);
}
}
Private Sub PrintRecursive(n As TreeNode)
System.Diagnostics.Debug.WriteLine(n.Text)
MessageBox.Show(n.Text)
Dim aNode As TreeNode
For Each aNode In n.Nodes
PrintRecursive(aNode)
Next
End Sub
' Call the procedure using the top nodes of the treeview.
Private Sub CallRecursive(aTreeView As TreeView)
Dim n As TreeNode
For Each n In aTreeView.Nodes
PrintRecursive(n)
Next
End Sub
private:
void PrintRecursive(TreeNode^ treeNode)
{
// Print the node.
System::Diagnostics::Debug::WriteLine(treeNode->Text);
MessageBox::Show(treeNode->Text);
// Print each node recursively.
System::Collections::IEnumerator^ myNodes = (safe_cast<System::Collections::IEnumerable^>(treeNode->Nodes))->GetEnumerator();
try
{
while (myNodes->MoveNext())
{
TreeNode^ tn = safe_cast<TreeNode^>(myNodes->Current);
PrintRecursive(tn);
}
}
finally
{
delete(myNodes);
}
}
// Call the procedure using the TreeView.
void CallRecursive(TreeView^ treeView)
{
// Print each node recursively.
TreeNodeCollection^ nodes = treeView->Nodes;
System::Collections::IEnumerator^ myNodes = (safe_cast<System::Collections::IEnumerable^>(nodes))->GetEnumerator();
try
{
while (myNodes->MoveNext())
{
TreeNode^ n = safe_cast<TreeNode^>(myNodes->Current);
PrintRecursive(n);
}
}
finally
{
delete(myNodes);
}
}
Non-recursive approach
The following example is an alternate iterative approach to traversing the nodes of the tree using a Queue<T> collection. This approach doesn't follow the parent-child relationship of a node only ensures every node is printed. If you want to process each tree node and its children, first, use the Stack<T> collection
private void PrintNonRecursive(TreeNode treeNode)
{
if (treeNode != null)
{
//Using a queue to store and process each node in the TreeView
Queue<TreeNode> staging = new Queue<TreeNode>();
staging.Enqueue(treeNode);
while (staging.Count > 0)
{
treeNode = staging.Dequeue();
// Print the node.
System.Diagnostics.Debug.WriteLine(treeNode.Text);
MessageBox.Show(treeNode.Text);
foreach (TreeNode node in treeNode.Nodes)
{
staging.Enqueue(node);
}
}
}
}
// Call the procedure using the TreeView.
private void CallNonRecursive(TreeView treeView)
{
// Print each node.
foreach (TreeNode n in treeView.Nodes)
{
PrintNonRecursive(n);
}
}
Private Sub PrintNonrecursive(n As TreeNode)
If n IsNot Nothing Then
Dim staging As Queue(Of TreeNode) = New Queue(Of TreeNode)
staging.Enqueue(n)
While staging.Count > 0
n = staging.Dequeue()
'Print the node.
System.Diagnostics.Debug.WriteLine(n.Text)
MessageBox.Show(n.Text)
Dim node As TreeNode
For Each node In n.Nodes
staging.Enqueue(node)
Next
End While
End If
End Sub
Private Sub CallNonRecursive(aTreeView As TreeView)
Dim n As TreeNode
For Each n In aTreeView.Nodes
PrintNonrecursive(n)
Next
End Sub
private:
void PrintNonRecursive(TreeNode^ treeNode)
{
//Using a queue to store and process each node in the TreeView
Queue^ staging = gcnew Queue();
staging->Enqueue(treeNode);
while (staging->Count > 0)
{
treeNode = safe_cast<TreeNode^>(staging->Dequeue());
// Print the node.
System::Diagnostics::Debug::WriteLine(treeNode->Text);
MessageBox::Show(treeNode->Text);
System::Collections::IEnumerator^ children = (safe_cast<System::Collections::IEnumerable^>(treeNode->Nodes))->GetEnumerator();
try
{
while (children->MoveNext())
{
staging->Enqueue(children->Current);
}
}
finally
{
delete(children);
}
}
// Print the node.
System::Diagnostics::Debug::WriteLine(treeNode->Text);
MessageBox::Show(treeNode->Text);
// Print each node recursively.
System::Collections::IEnumerator^ myNodes = (safe_cast<System::Collections::IEnumerable^>(treeNode->Nodes))->GetEnumerator();
try
{
while (myNodes->MoveNext())
{
TreeNode^ tn = safe_cast<TreeNode^>(myNodes->Current);
PrintRecursive(tn);
}
}
finally
{
delete(myNodes);
}
}
// Call the procedure using the TreeView.
void CallNonRecursive(TreeView^ treeView)
{
// Print each node recursively.
TreeNodeCollection^ nodes = treeView->Nodes;
System::Collections::IEnumerator^ myNodes = (safe_cast<System::Collections::IEnumerable^>(nodes))->GetEnumerator();
try
{
while (myNodes->MoveNext())
{
TreeNode^ n = safe_cast<TreeNode^>(myNodes->Current);
PrintNonRecursive(n);
}
}
finally
{
delete(myNodes);
}
}
See also
.NET Desktop feedback