How can I get the current node selected in a TreeView control?

vikasse picture vikasse · Jan 3, 2011 · Viewed 20k times · Source

When I use the MouseClick event of a treeview control always the first node in the tree is selected. What should I do to get the current node selected by the user? I am using C#.

This is the code I am currently using:

private void TVRecorder_MouseClick(object sender, MouseEventArgs e)
{
    TreeNode selectedNode = TVRecorder.HitTest(e.Location).Node;
    if (selectedNode != null)
    {
        if (selectedNode.SelectedImageKey == "Test_Space")
        {
            frmRepository rep = new frmRepository();
            string ssql = string.Empty;
            rep.label1.Text = "Scenario-RepositoryDetails";
            rep.LoadAppSettings();
            SqlConnection con4 = new SqlConnection();

            con4.ConnectionString = "Data Source=" + rep.ScnServer + ";" + "initial catalog=" + rep.ScnDbName + ";" + "User Id=" + rep.ScnUserName + ";" + "Password=" + rep.ScnPwd;
            try
            {
                con4.Open();
            }
            catch
            {
                MessageBox.Show("Connection Failed");
            }
            ssql = "scn_select_testplan_sp";
            SqlCommand cmd = new SqlCommand(ssql, con4);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@testspace_key", SqlDbType.Int);
            cmd.Parameters["@testspace_key"].Value = testspace_key;
            SqlDataReader _datareader = cmd.ExecuteReader();
            try
            {
                while (_datareader.Read())
                {
                    testplan_key = (int)_datareader["testplan_key"];
                    testplan_desc = (string)_datareader["testplan_desc"];
                    //selectedNode.Nodes[0].Nodes.Add(Convert.ToString(testplan_key), testplan_desc, "P", "Test_Plan");
                    TVRecorder.Nodes[0].Nodes.Add(Convert.ToString(testplan_key), testplan_desc, "P", "Test_Plan");
                    TVRecorder.Visible = true;
                    TVRecorder.HideSelection = false;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

Thanks in advance...

Answer

Cody Gray picture Cody Gray · Jan 3, 2011

You can use the HitTest method exposed by the TreeView control in conjunction with the location of the mouse pointer when the MouseClick event occurred (e.Location) to determine which node was clicked (and will therefore appear selected at the conclusion of the event). For example:

private void TreeView_MouseClick(object sender, MouseEventArgs e)
{
    // Get the node that was clicked
    TreeNode selectedNode = myTreeView.HitTest(e.Location).Node;

    if (selectedNode != null)
    {
        // ...
        // Do something with the selected node here...
    }
}

Notice that the above code checks to make sure that the selectedNode is not null before doing anything else with it. If the user clicked over something that is not a node, the selectedNode object that is retrieved by the HitTest method will be null.

It's probably not working for you now because you're trying to use the SelectedNode property of the TreeView control. The node hasn't yet been selected when the code in your MouseClick event handler method is running—it will only be selected after that code has executed. Using the above method instead will allow you to get at the node that will eventually be selected more directly.


EDIT concerning your update and comment below:

This looks to me like a simple fix. The problem occurs in this line of your code:

TVRecorder.Nodes[0].Nodes.Add(Convert.ToString(testplan_key), testplan_desc, "P", "Test_Plan");

The above code adds the new nodes as children of the first node appearing in your TreeView. Instead, it appears to me that you want to add them as children of the selected node. You've already determined what the selected node is (see above portion of answer), so you just need to modify your code to add the new nodes as children of the selected node, like so:

selectedNode.Nodes.Add(Convert.ToString(testplan_key), testplan_desc, "P", "Test_Plan");

Remember that every node (an instance of the TreeNode class) has a Nodes property that exposes a TreeNodeCollection. This collection holds all of that node's child nodes. MSDN probably explains this better than I can:

The Nodes property can hold a collection of other TreeNode objects. Each of the tree node[s] in the collection has a Nodes property that can contain its own TreeNodeCollection. This nesting of tree nodes can make it difficult to navigate a tree structure. The FullPath property makes it easier to determine your location in a tree.