C# ToolStripMenuItem显示下拉列表-事件不显示';t火

C# ToolStripMenuItem显示下拉列表-事件不显示';t火,c#,winforms,contextmenustrip,toolstripmenu,C#,Winforms,Contextmenustrip,Toolstripmenu,我想在DataGridView的右键单击上放置一个上下文相关菜单。我希望从单击的单元格的内容中派生一个菜单项,并从数据库中检索子菜单中可变数量的项 为此,我在ContextMenuStrip打开事件中构建ToolStripMenuItem。而且它很有效——几乎 如果我不显示子菜单,因此用户必须单击顶层菜单中的单个项目,一切都很好,但是如果我调用ShowDropDown方法自动显示子菜单,则单击项目时不会触发EXENT 下面是我可以生成的最简单的代码,用于重新创建问题-我已经提取了对DataGri

我想在DataGridView的右键单击上放置一个上下文相关菜单。我希望从单击的单元格的内容中派生一个菜单项,并从数据库中检索子菜单中可变数量的项

为此,我在ContextMenuStrip打开事件中构建ToolStripMenuItem。而且它很有效——几乎

如果我不显示子菜单,因此用户必须单击顶层菜单中的单个项目,一切都很好,但是如果我调用ShowDropDown方法自动显示子菜单,则单击项目时不会触发EXENT

下面是我可以生成的最简单的代码,用于重新创建问题-我已经提取了对DataGridView和数据库的所有引用,因此我的“动态”菜单是绝对静态的;-)

如果你把这是一个表单定义,右键点击表单上的任何地方,你会看到工作,但不是期望的行为-点击一个子菜单项,并看到一个弹出窗口。勾选复选框并再次右键单击,您将看到子菜单自动弹出-但单击项目不会触发别名单击处理程序

有什么想法吗?在这个特定的应用程序中,我可以编写一个非常有用的解决方案,避免使用ShowDropDown,但我想知道我做错了什么,以防将来需要使用它

public partial class Form1 : Form
{
    private ContextMenuStrip cms;
    private CheckBox chkAuto;

    public Form1()
    {
        InitializeComponent();

        chkAuto = new CheckBox();
        Controls.Add(chkAuto);

        cms = new ContextMenuStrip();
        cms.Opening += contextMenuStrip1_Opening;

        this.MouseClick += Form1_MouseClick;
    }

    private void Form1_MouseClick(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Right)
            cms.Show(Cursor.Position);
    }

    private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
    {
        cms.Items.Clear();
        ToolStripMenuItem tsmi = new ToolStripMenuItem("Title from datagridviewcell");
        tsmi.DropDownItems.Add(new ToolStripMenuItem("First item from database lookup", null, aliasClick));
        tsmi.DropDownItems.Add(new ToolStripMenuItem("Second item from database lookup", null, aliasClick));
        tsmi.DropDownItems.Add(new ToolStripMenuItem("Last item from database lookup", null, aliasClick));
        cms.Items.Add(tsmi);
        if (chkAuto.Checked)
            tsmi.ShowDropDown();
        e.Cancel = false;
    }
    private void aliasClick(object sender, EventArgs e)
    {
        ToolStripMenuItem clickedItem = (ToolStripMenuItem)sender;
        MessageBox.Show(clickedItem.Text);
    }
}

我不完全确定如何证明这一点,但我怀疑您对
tsmi.ShowDropDown()
的调用以某种方式导致单击处理程序无法正确捕获坐标。将其替换为cms.Show(鼠标位置),即可工作

也许从坐标中收集到一些有用的信息

var mi = new ToolStripMenuItem("First item from database lookup", null, aliasClick);
tsmi.DropDownItems.Add(mi);
var mi2 = new ToolStripMenuItem("Second item from database lookup", null, aliasClick);
tsmi.DropDownItems.Add(mi2);
var mi3 = new ToolStripMenuItem("Last item from database lookup", null, aliasClick);
tsmi.DropDownItems.Add(mi3);
cms.Items.Add(tsmi);
if (chkAuto.Checked)
    tsmi.ShowDropDown();
    //cms.Show(MousePosition);
Debug.WriteLine(mi.Bounds.ToString());

我已经做了一个快速修补,但尽管
cms.Show()
确实保留了事件处理程序,但它(据我所知)不会导致子菜单自动打开。我怀疑你对坐标的看法是对的,但我不知道该怎么办!好奇。在我的测试应用程序中,菜单按预期打开。如果你将鼠标悬停在顶级项目上或单击它,它将打开,但对我来说,它不会打开,否则。如果将cms从鼠标处打开,可能更容易发现:
private void Form1\u MouseClick(object sender,MouseEventArgs e){if(e.Button==System.Windows.Forms.MouseButtons.Right)cms.Show(新点(Cursor.Position.X+50,Cursor.Position.Y+50));}
我在家里的VS Express免费版上试用过,在VS Pro 2015上也试用过