Question Context Menu: How to detect run time menu items when selected?

BugMan

Well-known member
Joined
Dec 27, 2010
Messages
52
Location
Tallahassee FL
Programming Experience
10+
Using VB.Net 2010 Express: I can't figure out how to detect the run time menu option that was selected from a Context Menu Strip. I've added the control to a form, added one option at design time and can trap that event, but not the menu option added at run time.

Surely this is simple, but escapes me!

Thanks in advance.
-----------------------------------------------------

Public Class Form1

'a Context Menu Strip was added to the form and at Design time,
'an item named "ToolStripMenuItem1" was added to the Context Menu.
' At Run time, I add other options depending on user settings.
'How are these Run time menu clicks detected?

Private Sub ToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem1.Click

'Here the design time menu option is detected

MsgBox("Design Time Menu Item 1 clicked")

End Sub


Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

'Here a menu option is added at run time...
' menu item displays correctly, but how do we detect that it was clicked?

ContextMenuStrip1.Items.Add("Run Time Menu Item")

End Sub

End Class
 
hi,

1st. when posting code: use the CODE tag.

try adding the item like this:
VB.NET:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim Item As New ToolStripMenuItem
        Item.Text = "Text"
        Item.Name = "Itemname"
        ContextMenuStrip1.Items.Add(Item)
        AddHandler Item.Click, AddressOf Item_Click
End Sub

Private Sub Item_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        MessageBox.Show("Voilá")
End Sub

You can add all AddHandler of all your items to the same Sub and use a Select Case sender.Name or just have one sub for each... all will work fine.



you can also do the other way around (if possible), just add ALL the possible menu items and handlers on design-time and use the .Visible property to hide and show during runtime.
 
Budius,

Thanks very much. My apology for not being clearer... I'm still confused about how to tell which menu item was selected. If I understand it correctly, the code you gave only shows that the context menu was selected but doesn't say which item was clicked.

It's necessary to add the menu items at run time, unfortunately, as the menu options are determined by a settings file owned by the end user. Thanks also for the tip on the 'code' tag.
 
'sender' event parameter reveals the class instance that raised the event.

For the ItemClicked event information is given in the 'e' event parameter by the ClickedItem property.
 
'sender' event parameter reveals the class instance that raised the event.

For the ItemClicked event information is given in the 'e' event parameter by the ClickedItem property.

I'm struggling with these new (to me!) ways of doing things in .net after VB6... can you give an example of how to use the 'sender' event to determine which menu item was clicked? I feel like I'm so close to getting this, just can't make the connection. thanks John!
 
let me expand my initial example:

VB.NET:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
   ' 1st menu item
        Dim Item1 As New ToolStripMenuItem
        Item1.Text = "Text1"
        Item1.Name = "Itemname1"
        ContextMenuStrip1.Items.Add(Item1)

   ' 2nd menu item
        Dim Item2 As New ToolStripMenuItem
        Item2.Text = "Text2"
        Item2.Name = "Itemname2"
        ContextMenuStrip1.Items.Add(Item2)

   ' add handler for both items
        AddHandler Item1.Click, AddressOf Item_Click
        AddHandler Item2.Click, AddressOf Item_Click
End Sub

Private Sub Item_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

    Select Case sender.name
            Case "Itemname1":  MessageBox.Show("Item 1 was clicked")
            Case "Itemname2":  MessageBox.Show("Item 1 was clicked")
     End Select

End Sub


and in a very similar way, JohnH method would be something like:

VB.NET:
    Private Sub ContextMenuStrip1_ItemClicked(ByVal sender As Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles ContextMenuStrip1.ItemClicked
        Select Case e.ClickedItem.Name
            Case "item1": MessageBox.Show("Item 1 was clicked")
            Case "item2": MessageBox.Show("Item 2 was clicked")
            Case "item3"
        End Select
    End Sub

got it ?
 
'sender' is type Object because all .Net event uses this same event handler pattern. You can cast the 'sender' to expected type, here a ToolStripMenuItem:
VB.NET:
Dim item As ToolStripMenuItem = CType(sender, ToolStripMenuItem)

For ItemClicked event return type of e.ClickedItem property is ToolStripItem, which is a base class for ToolStripMenuItem. The Name property that was used in the previous code example is something the ToolStripMenuItem class inherits from ToolStripItem class, so it is valid to use in both cases. It is not necessary to cast the ClickedItem to type ToolStripMenuItem even though the item object in question really is that type, unless you need access to class members specific to that type.
 
Got it, Budius. Thanks so very much! BTW, I think you forgot to change the ' Item 1' to 'Item 2' in this line below, but it was obvious what you meant. Just in case anybody else is confused by it...


VB.NET:
 Case "Itemname2":  MessageBox.Show("Item 1 was clicked")
See, you got me to do the 'code' thing also!:eek:

Thanks again, HUGE help.
 
Back
Top