0

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.

1
  • I have edited you code and remove a seemingly redundant line, please check. Commented Oct 30, 2018 at 5:12

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

This is great - works fine. I replaced MessageBox.Show with code to show help depending on which submenu was clicked to. Many thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.