为以编程方式生成的上下文菜单子菜单捕获单击事件

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

我正在尝试在由以下代码动态创建的上下文菜单子菜单上捕获点击事件。在设计器中创建上下文菜单 cmList,并从属性菜单中添加单击事件代码。

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;
}

如何创建在单击任何上下文菜单项的子菜单时执行的代码,并使子菜单项的标识(在文本 属性 中设置)可用?

我尝试使用

添加事件处理程序
(cmListTags.Items[i] as ToolStripMenuItem).DropDownItems.Add(i.ToString(), Properties.Resources.InfoBig, new EventHandler(InfoClicked));

我在哪里创建函数

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

单击子菜单但 sender 和 e 都没有关于所单击的子菜单项的任何信息时调用此函数 - sender 为 null,e 为空。

如果我将 e 设置为类型 ToolStripItemClickedEventArgs 并将下拉添加行更改为

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

我得到 DropDownItems.Add 的最后一个参数的编译时类型不匹配。

您可以使用 anonymous method - 没有名称的方法体。

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

由于匿名方法是就地声明的,它可以访问局部变量i。所以这样你就不需要使用sender

Edit:原来是在for循环中修改了i。所以我必须使用本地副本 index 来保持它的价值。

关于你的第二个问题,

我得到 DropDownItems.Add 的最后一个参数的编译时类型不匹配。

这是因为InfoClicked的签名与委托人ToolStripItemClickedEventHandler的签名不匹配。