查找导致显示ContextMenuStrip菜单的控件 [英] Find control that caused ContextMenuStrip menu to be shown
问题描述
我已阅读了几篇关于SO的文章:
I've read a few articles on SO:
如何确定导致ContextMenuStrip的控件
获取对上下文菜单的控制
和其他一些建议使用SourceControl属性的其他人,但是没有工作在这个上下文中:
and a couple others that suggested use of the SourceControl property.. but none work in this context:
我有一个ContextMenuStrip有一个孩子ToolStripMenuItem - 这个代码从Windows窗体设计器生成的部分:
I have a ContextMenuStrip that has a child ToolStripMenuItem - this code from the windows forms designer generated section:
// _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:
So the context menu strip and the menu item first in the list are fixed at design time. At runtime, the TSMI has child TSMIs added to it in a loop based on an enum:
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设置为同样的事情:
Later I have 20 checkboxes on my form and I set their .ContextMenuStrip to be the same thing:
foreach(Thing t in someDataSource){
CheckBox c = new CheckBox();
c.Text = t.SomeData;
c.ContextMenuStrip = this._tileContextMenuStrip;
myPanelBlah.Controls.Add(c);
}
很好,所以现在我有所有的复选框,他们都显示上下文菜单当我右键单击它们,但是当我选择一个子菜单项时,我只是找不到控制,触发了上下文菜单...
Great, so now I have all my checkboxes and they all show the context menu when I right click them, but when I choose one the sub-menu items, I just can't find out the control that fired the context menu...
//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 ,或者甚至只是将ContextMenuStrip本身引用为一个表单实例变量,但是SourceControl总是为空
I can reliably get ahold of the contextmenustrip either by routing up from the event handler sender, or even just by referencing the ContextMenuStrip itself as a form instance variable, but SourceControl is always null
任何想法下一步要尝试什么?
Any ideas what to try next?
推荐答案
我看到这个问题,像一个bug一样大吵大闹,有一个解决方法,你可以订阅ContextMenuStrip的Opening事件,那么在开始导航之前子项目,SourceControl属性仍然有效,因此将其存储在类的一个字段中,以便您可以在Click事件处理程序中使用它。大致:
I see the problem, quacks loudly like a bug. There's a workaround, you can subscribe the ContextMenuStrip's Opening event. At that point, well before you start navigating into the sub-items, the SourceControl property is still valid. So store it in a field of the class so you'll have it available in the Click event handler. Roughly:
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
//...
}
这篇关于查找导致显示ContextMenuStrip菜单的控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!