Developer Solutions
In-depth answers to today's top programming questions.
How to Fix the Infinite Loop When Setting TreeView.SelectedNode to Null in C# WinForms
June 6, 2026 Source Question
Understanding the TreeView.AfterSelect Infinite Loop
When working with the Windows Forms TreeView control in C#, you might run into a frustrating issue: setting treeView1.SelectedNode = null inside the AfterSelect event handler triggers an infinite loop (eventually causing a StackOverflowException).
According to some older MSDN documentation, the AfterSelect event is not supposed to occur when a tree node is unselected. However, in practice, setting SelectedNode = null changes the selection state of the control, which programmatically fires the AfterSelect event again. If your event handler immediately sets the selection to null, it triggers itself recursively forever.
Fortunately, there are two highly effective and standard WinForms design patterns to resolve this issue.
Solution 1: Use a Re-entry Guard Flag (Recommended)
The cleanest and most common way to prevent event recursion is to use a private boolean flag. This flag tracks whether your code is currently updating the selection, allowing you to bypass the event logic when programmatically resetting the node.
private bool _isResettingSelection = false;
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
// If we are already resetting the selection, exit early to prevent recursion
if (_isResettingSelection) return;
try
{
// Perform your logic with the selected node
if (e.Node != null)
{
// Do work here...
}
// Set the flag and unselect the node
_isResettingSelection = true;
treeView1.SelectedNode = null;
}
finally
{
// Always reset the flag in a finally block to ensure it gets cleared
_isResettingSelection = false;
}
}Solution 2: Temporarily Unsubscribe from the Event
Another robust approach is to temporarily detach the event handler before you modify the SelectedNode property, and then reattach it immediately afterward. This guarantees that the event cannot be triggered by your programmatic change.
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
// Unsubscribe from the event to prevent recursive calls
treeView1.AfterSelect -= treeView1_AfterSelect;
try
{
// Your logic here...
// Safe to set to null now
treeView1.SelectedNode = null;
}
finally
{
// Re-subscribe to the event
treeView1.AfterSelect += treeView1_AfterSelect;
}
}Which Method Should You Choose?
- Use Solution 1 (The Flag) if you have multiple events or complex UI logic that might trigger cascading selection changes. It keeps your code predictable and centralized.
- Use Solution 2 (Unsubscribing) for simpler, self-contained event handlers where you want to ensure absolutely no event side-effects occur during the selection reset.