查找导致ContextMenuStrip菜单显示的控件



我读了一些关于SO:的文章

如何取消挖掘导致ContextMenuStrip的控件获得上下文菜单的控制

以及其他几个建议使用SourceControl属性的人。。但在这种情况下没有一个是有效的:

我有一个ContextMenuStrip,它有一个子ToolStripMenuItem——这段代码来自windows窗体设计器生成的部分:

// _tileContextMenuStrip
// 
this._tileContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tileKindToolStripMenuItem,
this.forceWidthScalingToolStripMenuItem,
this.forceHeightScalingToolStripMenuItem});
this._tileContextMenuStrip.Name = "_tileContextMenuStrip";
this._tileContextMenuStrip.Size = new System.Drawing.Size(184, 70);
// 
// tileKindToolStripMenuItem
// 
this.tileKindToolStripMenuItem.Name = "tileKindToolStripMenuItem";
this.tileKindToolStripMenuItem.Size = new System.Drawing.Size(183, 22);
this.tileKindToolStripMenuItem.Text = "Tile Kind";

因此,上下文菜单条和列表中第一个菜单项在设计时是固定的。在运行时,TSMI在一个基于枚举的循环中添加了子TSMI:

foreach(TileKind t in typeof(TileKind).GetEnumValues()) {
ToolStripMenuItem tsmi = new ToolStripMenuItem(t.ToString("g"));
tsmi.Tag = t;
tsmi.Click += tsmi_Click; 
tileKindToolStripMenuItem.DropDownItems.Add(tsmi);
}

稍后,我在表单上有20个复选框,我将它们的.ContextMenuStrip设置为相同的东西:

foreach(Thing t in someDataSource){
CheckBox c = new CheckBox();
c.Text = t.SomeData;
c.ContextMenuStrip = this._tileContextMenuStrip;
myPanelBlah.Controls.Add(c);
}

很棒,所以现在我有了所有的复选框,当我右键单击它们时,它们都会显示上下文菜单,但当我选择其中一个子菜单项时,我就是找不到触发上下文菜单的控件。。。

//this the click handler for all the menu items dynamically added
void tsmi_Click(object sender, EventArgs e)
{
ToolStripMenuItem tsmi = sender as ToolStripMenuItem;
(tsmi.OwnerItem                   //the parent node in the menu tree hierarchy
.Owner as ContextMenuStrip)   //it's a ContextMenuStrip so the cast succeeds
.SourceControl                //it's always null :(
}

我可以通过从事件处理程序发送器向上路由,甚至只通过将contextmenustrip本身引用为表单实例变量,可靠地获得contextMenuStap,但SourceControl始终为空

你知道下一步该怎么做吗?

我看到了问题,像虫子一样嘎嘎作响。有一个解决方法,您可以订阅ContextMenuStrip的Opening事件。此时,在开始导航到子项之前,SourceControl属性仍然有效。因此,将它存储在类的一个字段中,这样您就可以在Click事件处理程序中使用它。大致:

private Control _tileCmsSource;
private void _tileContextMenuStrip_Opening(object sender, CancelEventArgs e) {
_tileCmsSource = _tileContextMenuStrip.SourceControl;
}
void tsmi_Click(object sender, EventArgs e)
{
ToolStripMenuItem tsmi = sender as ToolStripMenuItem;
// Use _tileCmsSource here
//...
}

相关内容

  • 没有找到相关文章

最新更新