首页 > 解决方案 > 捕获以编程方式生成的上下文菜单子菜单的单击事件

问题描述

我正在尝试在由以下代码动态创建的上下文菜单子菜单上捕获单击事件。在设计器中创建上下文菜单 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 为空且 e 为空。

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

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

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

标签: c#contextmenu

解决方案


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

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

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

编辑:原来i正在 for 循环中被修改。所以我必须使用本地副本索引来保持它的价值。

至于你的第二个问题,

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

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


推荐阅读