Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 确定在哪个控件上使用了ContextMenuStrip_C#_.net_Winforms_Contextmenustrip - Fatal编程技术网

C# 确定在哪个控件上使用了ContextMenuStrip

C# 确定在哪个控件上使用了ContextMenuStrip,c#,.net,winforms,contextmenustrip,C#,.net,Winforms,Contextmenustrip,我有一个ContextMenuStrip,分配给几个不同的列表框。我正在试图弄清楚什么时候单击了ContextMenuStrip,在什么列表框上使用了它。我尝试了下面的代码作为开始,但它不工作。sender具有正确的值,但当我尝试将其分配给菜单submitted时,该值为空 private void MenuViewDetails_Click(object sender, EventArgs e) { ContextMenu menuSubmitted = sender as Conte

我有一个
ContextMenuStrip
,分配给几个不同的列表框。我正在试图弄清楚什么时候单击了
ContextMenuStrip
,在什么
列表框上使用了它。我尝试了下面的代码作为开始,但它不工作。
sender
具有正确的值,但当我尝试将其分配给
菜单submitted
时,该值为空

private void MenuViewDetails_Click(object sender, EventArgs e)
{
    ContextMenu menuSubmitted = sender as ContextMenu;
    if (menuSubmitted != null)
    {
        Control sourceControl = menuSubmitted.SourceControl;
    }
}
任何帮助都会很好。谢谢

通过下面的帮助,我找到了答案:

private void MenuViewDetails_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
            if (menuItem != null)
            {
                ContextMenuStrip calendarMenu = menuItem.Owner as ContextMenuStrip;

                if (calendarMenu != null)
                {
                    Control controlSelected = calendarMenu.SourceControl;
                }
            }
        }
对于
上下文菜单
: 问题是
sender
参数指向上下文菜单上单击的项目,而不是上下文菜单本身

不过,这是一个简单的解决方案,因为每个
MenuItem
都会公开一个菜单项,告诉您哪个
ContextMenu
包含该菜单项

将代码更改为以下内容:

private void MenuViewDetails_Click(object sender, EventArgs e)
{
    // Try to cast the sender to a MenuItem
    MenuItem menuItem = sender as MenuItem;
    if (menuItem != null)
    {
        // Retrieve the ContextMenu that contains this MenuItem
        ContextMenu menu = menuItem.GetContextMenu();

        // Get the control that is displaying this context menu
        Control sourceControl = menu.SourceControl;
    }
}
对于
ContextMenuStrip
: 如果您使用
ContextMenuStrip
而不是
ContextMenu
,它会稍微改变一些事情。这两个控件彼此不相关,不能将一个控件的实例强制转换为另一个控件的实例

与以前一样,单击的项目仍然会在
发送者
参数中返回,因此您必须确定拥有此单个菜单项的
ContextMenuStrip
。你可以用这个。最后,您将使用确定哪个控件显示上下文菜单

按如下方式修改代码:

private void MenuViewDetails_Click(object sender, EventArgs e)
{
     // Try to cast the sender to a ToolStripItem
     ToolStripItem menuItem = sender as ToolStripItem;
     if (menuItem != null)
     {
        // Retrieve the ContextMenuStrip that owns this ToolStripItem
        ContextMenuStrip owner = menuItem.Owner as ContextMenuStrip;
        if (owner != null)
        {
           // Get the control that is displaying this context menu
           Control sourceControl = owner.SourceControl;
        }
     }
 }

较旧的帖子,但万一像我这样的人遇到:

对于一个ContextMenuStrip来说,上面的内容对我来说不起作用,但它让我找到了真正起作用的东西

void DeleteMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
    ContextMenuStrip menu = sender as ContextMenuStrip;
    Control sourceControl = menu.SourceControl;
    MessageBox.Show(sourceControl.Name);
}

这给了我预期控件的名称。您可以使用if语句进行验证等,我只是想说明问题。

我很难让这些代码正常工作。这是我能找到的最简单的解决方案:

对于ContextMenuStrip:
最简单的解决办法是:

Control parentControl = ((sender as MenuItem).GetContextMenu()).SourceControl;
 

将发送者强制转换为ToolStripItem以到达所有者,该所有者将是不具有SourceControl属性的ToolStrip

将所有者强制转换为ContextMenuStrip以访问SourceControl

Control sc = ((ContextMenuStrip)((ToolStripItem)sender).Owner).SourceControl;

在本例中,使用C1网格中的ActiveForm.ActiveControl如何:

C1.Win.FlexGrid.C1FlexGrid fg = frmMain.ActiveForm.ActiveControl as C1.Win.FlexGrid.C1FlexGrid;

@蓝脚:那么你又出了什么问题。我刚刚用三个不同的列表框测试了这段代码,一切都按预期进行了。发布更多的复制代码。@bluefeet:我已经在我的答案中更新了代码。
ContextMenu
ContextMenuStrip
之间有很大区别。(啊,我看你已经弄明白了。好吧,最好是自己学习!)我使用打开事件来记录将菜单打开到局部变量的SourceControl,然后在处理项目单击时引用它。@QuickDanger是的,
SourceControl
在触发
ContextMenuStrip
ToolStripItem
子项的
Click
事件时不幸为空。似乎
ContextMenuStrip
Closed
事件在
单击事件之前触发,这可能是导致问题的原因;我假设该属性在菜单“关闭”后被清除。@CodyGray实际上,如果树更深,则必须循环
OwnerItem
属性链,直到找到
ToolStripItem
ContextMenuStrip
属性。但正如我刚才评论的,它不起作用;上下文菜单上的
SourceControl
将为空。但是你说你不能复制它。。。也许问题只发生在菜单深度超过一个级别时?我的是两个子层深。谢谢你的解决方案,我一直在寻找。我也有同样的问题。但是我建议不要嵌套所有那些
if
语句并使用
if(menuItem==null)返回如果你和我一样,不希望处理它的代码嵌套在额外的不必要的两个级别。在我看来,你提供的解决方案可以更简洁地编码:
controlcontrolselected=((发送者作为ToolStripMenuItem)?.Owner作为ContextMenuStrip)?.SourceControl这仅适用于
上下文菜单中的直接项。问题是单击子菜单项时,
ItemClicked
不会触发;他们需要自己的
点击
事件,该事件将项目本身作为发件人,而不是菜单。我认为此代码更简单,谢谢
C1.Win.FlexGrid.C1FlexGrid fg = frmMain.ActiveForm.ActiveControl as C1.Win.FlexGrid.C1FlexGrid;