简体   繁体   中英

Trapping a click event for a programmatically generated context menu sub-menu

I am trying to catch a click event on a context menu submenu created dynamically by the following code. The context menu cmList is created in the designer, and the click event code is added from the properties menu.

for (int i = 0; i <= sTagsContext.GetUpperBound(0); i++)
{
    cmListTags.Items.Add(sTagsContext[i]);
    ToolStripMenuItem submenu = new ToolStripMenuItem();                  
    submenu.Text = i.ToString();
    submenu.Image = Properties.Resources.InfoBig;

    (cmListTags.Items[i] as ToolStripMenuItem).DropDownItems.Add(submenu);                    
     chkListTags.ContextMenuStrip = cmListTags;
}

How can I create code to be executed when the submenu of any of the context menu items is clicked and have the identity of the submenu item (set in the text property) available?

I have tried adding an event handler using

(cmListTags.Items[i] as ToolStripMenuItem).DropDownItems.Add(i.ToString(), Properties.Resources.InfoBig, new EventHandler(InfoClicked));

where I create the function

public void InfoClicked(object sender, EventArgs e)
{
}

This function is called when the sub-menu is clicked but neither sender nor e has any information about the sub-menu item clicked - sender is null and e is empty.

If I set e to be type ToolStripItemClickedEventArgs and change the Dropdown addition line to

(cmListTags.Items[i] as ToolStripMenuItem).DropDownItems.Add(i.ToString(), Properties.Resources.InfoBig, new ToolStripItemClickedEventHandler(InfoClicked));

I get a compile time type mismatch for the last parameter of DropDownItems.Add.

You can use an anonymous method - a method body without a name.

int index = i;
cmListTags.Items[i] as ToolStripMenuItem).DropDownItems.Add(
     i.ToString(), 
     Properties.Resources.InfoBig, 
     (s, args) => {
         MessageBox.Show(index.ToString(); 
} ));

Since the anonymous method is declared in place , it has access to the local variable i . So in this way you don't need to use sender .

Edit : Turns out i is being modified in the for loop. So I have to use a local copy index to keep its value.

And as to your 2nd question,

I get a compile time type mismatch for the last parameter of DropDownItems.Add.

This is because the signature of InfoClicked does not match the signature of delegate ToolStripItemClickedEventHandler .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM