Click here to Skip to main content
Click here to Skip to main content

Tagged as

Go to top

Test if a TreeNode was actually clicked

, 20 Nov 2013
Rate this:
Please Sign up or sign in to vote.
Test if a TreeNode was expanded or collapsed rather than actually clicked.

Introduction

I'm working on a project manager type of application with a pretty straightforward design: projects and their constituent steps are read from the database and displayed hierarchically as nodes in a TreeView control. Clicking on a project or step node retrieves the details and generates a tab in an adjoining TabControl. This was being handled by intercepting the tree's NodeMouseClick event and was working great.

The problem was that expanding or collapsing a project node also triggered NodeMouseClick. I needed to figure out how to perform my action when the node was actually clicked, and not when the expand / collapse bullet next to the node was clicked.

The blindingly obvious solution

I spent a while searching the web and trying the offered solutions. All were along the lines of "intercept an earlier event, test to see what happened, then set a global variable that will be read in a later event." None of these solutions could be adapted to what I needed. So I started poking around and found the solution in the event's own parameter.

NodeMouseClick receives TreeNodeMouseClickEventArgs. This class contains Node, which gives the tree node that was clicked, and Location, which gives the mouse's position relative to the tree's client space when the click occurred. Tree nodes have a property, Bounds, which gives the node's rectangle coordinates relative to the tree view. A quick test verified that the expand / collapse bullet is outside the node's boundary. So I added

e.Node.Bounds.Contains(e.Location)
to my button test in the event and voila! I could perform the action only when the node was really clicked, and not when its collapse state was changing. In VB, this looks like:
Private Sub CurrentTree_NodeMouseClick(ByVal sender As Object, _
ByVal e As TreeNodeMouseClickEventArgs) _
Handles CurrentTree.NodeMouseClick
    If e.Node.Bounds.Contains(e.Location) AndAlso e.Button = Windows.Forms.MouseButtons.Left Then
        'Code to load project details and generate a tab
    End If
End Sub
In C#:
void CurrentTree_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    if (e.Node.Bounds.Contains(e.Location) && e.Button == MouseButtons.Left)
    {
        // Code to load project details and generate a tab
    }
}

Works like a charm, at least with .Net 3.5. I don't expect it would be different with any other flavors of the Framework.

Update 1: Made some minor grammar changes, clarified a few points, and added a C# example. I mostly use VB, so please let me know if the C# code is off.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Gregory Gadow
Software Developer (Senior)
United States United States
Gregory Gadow lives in Seattle, Washington and has been writing code for almost 25 years in more than a dozen programming languages. He works for a mid-size brokerage firm and holds the Series 7 and Series 66 brokerage licenses, but much prefers working as the company's programming department doing VB6, VB.Net, ASP, HTML, XML and SQL.

Comments and Discussions

 
QuestionFive PinmemberAlan Burkhart11-Nov-13 17:40 
GeneralMy vote of 5 PinmemberpeteSJ8-Nov-13 11:45 
Questioncan you upload the project? PinmemberMember 103894078-Nov-13 9:21 
AnswerRe: can you upload the project? PinmemberGregory.Gadow8-Nov-13 10:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140916.1 | Last Updated 20 Nov 2013
Article Copyright 2013 by Gregory Gadow
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid