c# - 捕获以编程方式生成的上下文菜单子菜单的单击事件
问题描述
我正在尝试在由以下代码动态创建的上下文菜单子菜单上捕获单击事件。在设计器中创建上下文菜单 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 的最后一个参数的编译时类型不匹配。
解决方案
您可以使用匿名方法- 没有名称的方法体。
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
。
推荐阅读
- ansible - 如何组合一堆具有相同缓慢设置和拆卸的 Ansible 剧本?
- java - 如何从 javafx.scene.image.Image 对象中获取字节数组?
- sockets - boost async_accept 不适用于 boost asio use_future 选项
- javascript - 使用“GMT”获取“toISOString”字符串详细信息
- oracle - CURRENT_DATE 甲骨文
- firebase - Firedatabase.SetPersistent (true) minimiza 下载数据吗?
- python - 如何使用管道中的最佳估计器来预测测试集?
- python - AI 问题(即使不应该发生碰撞)
- awk - 将文本添加到由 sed 中的某些特殊字符定义的特定块
- angular - app-routing.module.ts 可以有 2 条路径:/id