查找导致显示ContextMenuStrip菜单的控件 [英] Find control that caused ContextMenuStrip menu to be shown

查看:264
本文介绍了查找导致显示ContextMenuStrip菜单的控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已阅读了几篇关于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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆