Help with dynamic ContextMenuLists

Funger

Member
Joined
Dec 15, 2006
Messages
8
Programming Experience
5-10
Hi All,

I am creating and assigning ContextMenuList objects to individual TreeNode objects during runtime.

When a ContextMenuItem.Click event fires, how do I access the TreeView Node that the ContextMenuList belongs to?

Thanks in advance!

-Jim
 
Get the Location of the menu item owner (the contextmenustrip), translate this Point to Treeview coordinates and use the GetNodeAt method to get the treenode.
VB.NET:
Private Sub TestToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles TestToolStripMenuItem.Click
    Dim item As ToolStripMenuItem = sender
    Dim node As TreeNode = TreeView1.GetNodeAt(TreeView1.PointToClient(item.Owner.Location))
    Me.Text = node.Text
End Sub
 
I can't find a direct reference from the contextmenu to the node (SourceControl only returns the TreeView), but here's two other options that are better than the first suggestion. Reason is when there is not enough room the context menu location is no longer at the node that called it, it will offset so the full menu is visible, consequently the GetItemAt method would return wrong node or Nothing.

Normally only Left-click (or keyboard navigation) selects a node, when you Right-click to get contextmenu the node appears selected but it isn't. After menu is dismissed the real selected node is highlighted again. If you don't mind setting the SelectedNode also for Right-clicks then do this: (* actually don't do this, it's not good UI behaviour to set state directly with right mouse click, the next suggestion below where you just use the information to handle the context request is better UI design.)
VB.NET:
Private Sub TestToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles TestToolStripMenuItem.Click
    Me.Text = TreeView1.SelectedNode.Text
End Sub

Private Sub TreeView1_NodeMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeNodeMouseClickEventArgs) _
Handles TreeView1.NodeMouseClick
    If e.Button = Windows.Forms.MouseButtons.Right Then
        TreeView1.SelectedNode = e.Node
    End If
End Sub
Navigating and calling contextmenu with keyboard will already change the SelectedNode.

If you don't want the SelectedNode to change when retrieving contextmenu with mouse you have to catch the node at MouseDown, store it in a class level variable for use in menu item click event handler. If doing this you also have to take into account that user can navigate and call context menu with keyboard (Apps key or Shift-F10), for both these cases the SelectedNode have to be stored in the same variable used for mouse context. Example:
VB.NET:
Private Sub TestToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles TestToolStripMenuItem.Click
    Me.Text = contextNode.Text
End Sub

Private contextNode As TreeNode

Private Sub TreeView1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) _
Handles TreeView1.KeyDown
    If e.KeyCode = Keys.Apps _
    Or (e.Shift = True AndAlso e.KeyCode = Keys.F10) Then
        contextNode = TreeView1.SelectedNode
    End If
End Sub

Private Sub TreeView1_NodeMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeNodeMouseClickEventArgs) _
Handles TreeView1.NodeMouseClick
    If e.Button = Windows.Forms.MouseButtons.Right Then
        contextNode = e.Node
    End If
End Sub
 
Last edited:
Back
Top