Anil kumar Anil kumar - 2 months ago 19
C# Question

Winform C# : Node selection on expansion and collapse gets change at the bottom of the Treeview

I am using a Treeview in my windows form but getting some issue. My Node selection on expansion and collapse gets change at the bottom of the Treeview. I am using afterselect and MosueDown event. My problem is I have to deal with AfterSelect and MouseDown event both in my app as I am using Right click context menu as well. Below is the sample code that I am trying to use. Is there a way or advice to resolve this issue?

private void trView_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
trView.SelectedNode = trView.GetNodeAt(e.X, e.Y);
}
//trView.SelectedNode.EnsureVisible(); //tried this as well

trView.SelectedNode.Toggle(); // on this toggle selection changes butonly at the bottom (more specifically for last 3 nodes)
}

private void trView_AfterSelect(object sender, TreeViewEventArgs e)
{
// Code to add child nodes to a selection.
}


enter image description here

In the above pic when I am selecting Project Beyond Node, UAT Data gets selected. This is only happening in last 3 nodes. I am stuck. Please help.

Answer

You can use either of these options:

  1. Use MouseDown event, and after setting SelectedNode, Toggle it using BeginInvoke:

    private void treeView1_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            treeView1.SelectedNode = treeView1.GetNodeAt(e.X, e.Y);
            treeView1.BeginInvoke(new Action(() => { treeView1.SelectedNode.Toggle(); }));
        }
    }
    
  2. Use NodeMouseClick event:

    private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            treeView1.SelectedNode = treeView1.GetNodeAt(e.X, e.Y);
            treeView1.SelectedNode.Toggle();
        }
    }
    

Note

In general performing toggle should be done after click on +/- because selection is a different operation than clicking on +/-. But you can simply mix some criteria based on var node = treeView1.GetNodeAt(e.X, e.Y) and var hti = treeView1.HitTest(e.Location); and e.Button to satisfy any requirement on mouse down.

For example in below code, the left click and right click works in the same way, both of them select the node and both toggle the selected node.

private void treeView1_MouseDown(object sender, MouseEventArgs e)
{
    var node = treeView1.GetNodeAt(e.X, e.Y);
    var hti = treeView1.HitTest(e.Location);
    if (node == null)
        return;
    treeView1.BeginInvoke(new Action(() => treeView1.SelectedNode = node));
    if (e.Button == System.Windows.Forms.MouseButtons.Right)
    {
        node.Toggle();
    }
    else if (e.Button == System.Windows.Forms.MouseButtons.Left)
    {
        if (hti.Location != TreeViewHitTestLocations.PlusMinus)
            node.Toggle();
    }
}