88

我有一个ContextMenuStrip分配给几个不同的列表框。我试图弄清楚什么时候ContextMenuStrip点击了ListBox它的用途。我尝试了下面的代码作为开始,但它不起作用。具有正确的sender值,但是当我尝试将其分配给它时,menuSubmitted它为空。

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;
                }
            }
        }
4

6 回答 6

132

对于一个ContextMenu

问题是sender参数指向上下文菜单上被单击的项目,而不是上下文菜单本身

不过,这是一个简单的修复,因为每个都MenuItem公开了一个GetContextMenu方法,该方法会告诉您哪个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

如果您使用 aContextMenuStrip而不是 a ,它确实会稍微改变一些事情ContextMenu。这两个控件彼此不相关,一个的实例不能转换为另一个的实例。

和以前一样,被点击的项目仍然在sender参数中返回,所以你必须确定ContextMenuStrip拥有这个单独的菜单项的人。您对Owner属性执行此操作。最后,您将使用该SourceControl属性来确定哪个控件正在显示上下文菜单。

像这样修改您的代码:

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;
        }
     }
 }
于 2011-02-03T12:56:23.477 回答
5

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

对于 ContextMenuStrip:

    Control _sourceControl = null;
    private void contextMenuStrip_Opened(object sender, EventArgs e)
    {
        _sourceControl = contextMenuStrip.SourceControl;
    }

    private void contextMenuItem_Click(object sender, EventArgs e)
    {
        var menuItem = (ToolStripMenuItem)sender;

        _sourceControl.Text = menuItem.Text;
        MessageBox.Show(menuItem.Name);
        MessageBox.Show(sourceControl.Name);
    }
于 2019-07-02T10:43:47.850 回答
4

较旧的帖子,但如果像我这样的人遇到它:

对于 ContextMenuStrip,上面的方法对我不起作用,但它导致找到起作用的方法。

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

这给了我预期的控件的名称。您可以使用 if 语句进行验证等,我只是发布到这一点。

于 2015-07-29T20:18:18.307 回答
2

将 sender 投射到 ToolStripItem 以到达 Owner,这将是一个没有 SourceControl 属性的 ToolStrip。

将 Owner 转换为 ContextMenuStrip 以到达 SourceControl。

Control sc = ((ContextMenuStrip)((ToolStripItem)sender).Owner).SourceControl;
于 2021-03-19T06:24:20.623 回答
0

最简单的解决方案是:

Control parentControl = ((sender as MenuItem).GetContextMenu()).SourceControl;
 
于 2020-07-16T12:23:57.407 回答
0

仅使用 ActiveForm.ActiveControl 怎么样,在此示例中来自 C1 网格:

C1.Win.FlexGrid.C1FlexGrid fg = frmMain.ActiveForm.ActiveControl as C1.Win.FlexGrid.C1FlexGrid;
于 2021-06-07T19:19:07.793 回答