c# - 从嵌套的 ToolStripMenuItem 检索时,ContextMenuStrip.Owner 属性为 null

标签 c# .net winforms contextmenustrip

我有一个带有两个 ToolStripItemContextMenuStrip 设置。第二个 ToolStripItem 有两个额外的嵌套 ToolStripItem。我将其定义为:

ContextMenuStrip cms = new ContextMenuStrip();
ToolStripMenuItem contextJumpTo = new ToolStripMenuItem();
ToolStripMenuItem contextJumpToHeatmap = new ToolStripMenuItem();
ToolStripMenuItem contextJumpToHeatmapStart = new ToolStripMenuItem();
ToolStripMenuItem contextJumpToHeatmapLast = new ToolStripMenuItem();

cms.Items.AddRange(new ToolStripItem[] { contextJumpTo,
                                         contextJumpToHeatmap});
cms.Size = new System.Drawing.Size(176, 148);

contextJumpTo.Size = new System.Drawing.Size(175, 22);
contextJumpTo.Text = "Jump To (No Heatmapping)";

contextJumpToHeatmap.Size = new System.Drawing.Size(175, 22);
contextJumpToHeatmap.Text = "Jump To (With Heatmapping)";
contextJumpToHeatmap.DropDownItems.AddRange(new ToolStripItem[] { contextJumpToHeatmapStart, 
                                                                  contextJumpToHeatmapLast });

contextJumpToHeatmapStart.Size = new System.Drawing.Size(165, 22);
contextJumpToHeatmapStart.Text = "From Start of File";

contextJumpToHeatmapLast.Size = new System.Drawing.Size(165, 22);
contextJumpToHeatmapLast.Text = "From Last Data Point";

然后我为我想要响应的三个 ToolStripMenuItem 的点击事件设置了一个事件监听器。下面是方法(我只列出了三种方法中的两种):

void contextJumpTo_Click(object sender, EventArgs e)
{
    // Try to cast the sender to a ToolStripItem 
    ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
    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 
            DataGridView dgv = owner.SourceControl as DataGridView;
            if (dgv != null)
                // DO WORK
        }
    } 
}

void contextJumpToHeatmapStart_Click(object sender, EventArgs e)
{
    // Try to cast the sender to a ToolStripItem 
    ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
    if (menuItem != null)
    {
        // Retrieve the ToolStripItem that owns this ToolStripItem 
        ToolStripMenuItem ownerItem = menuItem.OwnerItem as ToolStripMenuItem;
        if (ownerItem != null)
        {
            // Retrieve the ContextMenuStrip that owns this ToolStripItem 
            ContextMenuStrip owner = ownerItem.Owner as ContextMenuStrip;
            if (owner != null)
            {
                // Get the control that is displaying this context menu 
                DataGridView dgv = owner.SourceControl as DataGridView;
                if (dgv != null)
                    // DO WORK
            }
        }
    }
}

这是我遇到的问题:

我的 contextJumpTo_Click 方法工作得很好。我们一直深入到确定点击来自哪个 DataGridView 的位置,然后我可以继续。但是,contextJumpTo ToolStripMenuItem 不是 ContextMenuStrip 上的嵌套菜单项。

但我的 contextJumpToHeatmapStart_Click 方法无法正常工作。当我到达确定 owner.SourceControl 的行时,SourceControl 为 null,我无法继续。现在我知道这个 ToolStripMenuItem 嵌套在我的 ContextMenuStrip 中的另一个下面,但是为什么 SourceControl 属性突然在我的 ContextMenuStrip 上为空?

如何获取 ContextMenuStrip 的嵌套 ToolStripMenuItemSourceControl

最佳答案

我认为这是一个错误。

我尝试向上爬取工具条父项列表以找到 ContextStripMenu 所有者,这行得通,但 SourceControl 属性始终为 null。

看起来常见的解决方法是在打开上下文菜单时设置控件:

private Control menuSource;

cms.Opening += cms_Opening;

void cms_Opening(object sender, CancelEventArgs e) {
  menuSource = ((ContextMenuStrip)sender).SourceControl;
}

然后你的代码基本上变成这样:

DataGridView dgv = menuSource as DataGridView;
if (dgv != null) {
  // do work
}

关于c# - 从嵌套的 ToolStripMenuItem 检索时,ContextMenuStrip.Owner 属性为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12094528/

相关文章:

c# - 单行文本 - 电子邮件格式选项错误

c# - 在 .Net 2.0 中关闭 SerialPort 时出现 ObjectDisposedException

c# - Twain 驱动程序 - Windows OS x64 中的 TWAINDSM.DLL 错误

c# - 数据绑定(bind) Winforms 文本框

c# - 用大写字母拆分字符串

c# - 通过包含对象名称指定部分的字符串(或整数)引用对象的属性 - C#

c# - 动态 CRM SDK : Batch update specific fields in entity

c# - 当属性之一可以为 null 时 GetHashCode

c# - 无法在 RichTextBox 中处理 Ctrl + S

c# - 使用 CET 将 C# 字符串解析为日期时间