确定使用ContextMenuStrip的控件

时间:2011-02-03 12:47:52

标签: c# .net winforms contextmenustrip

我有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;
                }
            }
        }

任何帮助都会很棒。感谢。

使用下面的帮助,我想出来了:

{{1}}

6 个答案:

答案 0 :(得分:105)

对于ContextMenu

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

这是一个简单的修复,因为每个MenuItem都会公开GetContextMenu method,它会告诉您哪个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,它会稍微改变一下。这两个控件彼此不相关,并且一个实例不能被转换为另一个控件的实例。

与以前一样,单击的仍会在sender参数中返回,因此您必须确定拥有此单个菜单项的ContextMenuStrip。您可以使用Owner property执行此操作。最后,您将使用SourceControl property来确定哪个控件正在显示上下文菜单。

修改你的代码:

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

答案 1 :(得分:3)

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

对于ContextMenuStrip,上面的内容对我来说不起作用,但它导致找到了什么。

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

这给了我预期的控制名称。您可以使用if语句进行验证等,我只是发帖以达到目的。

答案 2 :(得分:1)

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

对于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);
    }

答案 3 :(得分:0)

最简单的解决方案是:

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

答案 4 :(得分:0)

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

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

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

答案 5 :(得分:0)

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

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