Detemining the "owner" of a ContextMenuStrip

I'm working on a project that utilizes a TableLayoutPanel containing many controls. The controls can be one of three types, and each type has an associated ContextMenuStrip.

I have it working where the ContextMenuStrip is applied to it's respective controls within the TLP, and can show and select items from the CMS, but need to be able to determine specifically what control was was right-clicked to show the CMS or the Point of that right click.

Thanks for any help!


Answer this question

Detemining the "owner" of a ContextMenuStrip

  • scoman81

    I was trying to avoid being critical of your approach, you wouldn't have to use a Rube Goldberg style approach if your design wasn't flawed in the first place. A better design would be to create a context menu for each different type of control. At design time add the menu items specific to each type of control to their respective contextmenus. At runtime you could copy menu items that are common to all controls onto all of the contextmenus. The problem with your approach is that one control could have focus and the user could right-click over another control and the common context menu would appear, the user could click one of the menu items thinking that he is activating the menu on the control that his mouse is over but he would actually be activating the menu over the focused control.


  • infrandom

    Try this:

    For Each c As Control In Me.Controls

    If c.ContextMenuStrip.Name Is CType(sender, ToolStripMenuItem).Owner.Name Then

    'Your code here

    Exit For

    End If

    Next


  • GlennZarb

    Use the 'sender' object ...it can be cast to the correct object type to determine which object fired the event



  • JBlackburn__

    That definitely helped me out quite a bit, thanks.

  • Damien Morton

    Even if you have 20 controls of the same type, the sender object once cast will give you the exact control that you right clicked.


  • NitinAgarwal

    Something like this in the click event

    Dim TheControl as Object
    TheControl = CType(CType(sender, ToolStripMenuItem).Owner, ContextMenuStrip).SourceControl

    Then you can inspect TheControl for .Type, .Name, etc. in a Select statement.


  • Jubber

    In C# it would be this in your ToolStripMenuItem click event:

    ToolStripMenuItem myItem = (ToolStripMenuItem)sender;

    ContextMenuStrip myStrip = (ContextMenuStrip)myItem.Owner;

    Button clickedButton = (Button)(myStrip.SourceControl);

    I hope it helps a little.


  • Benke

    The issue I was faced with was that I was trying to keep my code within the Click event of the ToolStripItem. It's sender was the ContextMenuStrip, which had no obvious property to tell me what opened it.

  • Hossam Abdel Wahab

    That would work if every control had a unique ContextMenuStrip, however, it's each *type* of control that has one. If I have 20 controls of each type on the TableLayoutPanel then it will execute code against all 20 controls, where I only want it against the single control that I right-clicked on

  • GrandpaB

    I've come up with an indirect workaround that serves my needs--but would still like to know if there is a more direct way.

    I declare a class-variable:
    dim mpntRightClick as point

    Then I add a MouseDown handler to every control in the TableLayoutPanel
    for each ctl as Control in TableLayoutPanel.Control
    addhandler ctl.mousedown, addressof ctlMouseDown_Handler
    next

    Then in the handler I check if it's a right-click and save the point of it if so
    private sub ctlMouseDown_Handler(byval sender as object, e as mouseeventargs)
    if e.button = right then
    mpntRightClick = e.location
    endif
    end sub

    Now when I get to the click handler for the items int he ContextMenuStrip I can referance mpntRightClick to determine what control I'm over.

    It's ugly, but it works.

  • Pratyush

    I've tried doing something like that. I can get to the ContextMenuStrip itself, but can't find a property that tells me what control it was opened on..

    DirectCast(sender, ToolStripMenuItem).Owner.Location

    *I've been using the ContextMenuStrip's Location property for the time being, which works unless the control I'm opening it on is located at the bottom of the screen.

  • bala_excel

    How about this:

    Code Snippet

    Dim ac As String

    Dim mbutton As Boolean

    Dim mlistbox As Boolean

    Dim mcombobox As Boolean

    Private Sub TestToolStripMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles TestToolStripMenuItem.Click

    Select Case ac

    Case "Button1"

    MsgBox(Button1.Name)

    Case "ListBox1"

    MsgBox(ListBox1.Name)

    Case "ComboBox1"

    MsgBox(ComboBox1.Name)

    End Select

    End Sub

    Private Sub ContextMenuStrip1_Opening(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip1.Opening

    'set variable to active control name

    ac = Me.ActiveControl.Name

    'if the mouse is not over the active control do not show the menu

    Select Case ac

    Case "Button1"

    If Not mbutton Then

    e.Cancel = True

    End If

    Case "ListBox1"

    If Not mlistbox Then

    e.Cancel = True

    End If

    Case "ComboBox1"

    If Not mcombobox Then

    e.Cancel = True

    End If

    End Select

    End Sub

    Private Sub Button1_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.MouseEnter

    mbutton = True

    End Sub

    Private Sub Button1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.MouseLeave

    mbutton = False

    End Sub

    Private Sub ListBox1_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.MouseEnter

    mlistbox = True

    End Sub

    Private Sub ListBox1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.MouseLeave

    mlistbox = False

    End Sub

    Private Sub ComboBox1_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.MouseEnter

    mcombobox = True

    End Sub

    Private Sub ComboBox1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.MouseLeave

    mcombobox = False

    End Sub


  • Steve Graber

    I haven't taken the time to go through this solution, but just wanted to say my intentions of this post were mainly to find out if I was overlooking some obvious property within the Click event of the ToolStripItem...

    However, if I could give you a Rube Goldberg award I would :-P -- Seriously though, thank you for the response and solution :-)

  • Detemining the "owner" of a ContextMenuStrip