Search code examples
c#eventstreeviewlag

.NET Treeview NodeMouseClick Event has lag?


I have this code:

private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (treeView1.SelectedNode.Nodes.Count == 0)
            {
                MessageBox.Show("The node does not have any children.");
            }
        }

When a treeView node which has no children is clicked, there seems to be a lag on the event firing.

For example:

  1. I click on a parent node with children - MessageBox does not fire
  2. I click on a child node without children - MessageBox does not fire
  3. I click on a child node without children again - Messagebox fires
  4. I click on a parent node with children - Messagebox fires
  5. I click on a parent node with children again - messagebox does not fire.

During debug, the SelectedNode.Count value seems to be the number from the click before it.

What is going on here?


Solution

  • Your problem stems from the fact that the OnNodeMouseClick is fired before any selection-related events (OnBeforeSelect & OnAfterSelect) which means the SelectedNode you're inspecting has not been updated yet.

    If you only care about the selection changing, then subscribe to BeforeSelect (with the ability to cancel the selection) or AfterSelect instead. This will handle changing selections using the keyboard as well.

    Unlike the selection-related events, NodeMouseClick will still trigger even if the the selected node is not changing (e.g. you're clicking on an already-selected node). Also, as the name implies, this only works on mouse click and not when using the keyboard to navigate your tree.

    To see what is actually happening in the background, you can have a look at the source code for TreeView, specifically the WmNotify method. You'll see that NodeMouseClick is triggered by a windows NM_CLICK message. It then performs a Hit Test at the clicked (x,y) coordinate to look for a node under the mouse, and if found, give it back to you inside the TreeNodeMouseClickEventArgs argument of the event.

    TLDR: When subscribing to NodeMouseClick, your selection hasn't changed yet (and it might not be changing), but you can see the clicked node by inspecting the event arg. Only works when using mouse, not keyboard.