单击MenuItem时,WinForms ContextMenu保持打开状态

时间:2017-03-17 15:29:47

标签: c# winforms datagridview contextmenu .net-4.5

所以我有一个表单DataGridView,当我右键单击网格时,我想显示一个上下文菜单,里面有一个菜单项。该菜单项将打开第二个表单,该表单将为DataGridView提供一些配置选项。

现在所有这些工作都非常好,上下文菜单正确显示,第二个表单正确打开,该表单上的所有功能都能正常工作。

唯一的问题是,只有点击菜单项以外的任何地方,上下文菜单才会关闭。无论我点击菜单项多少次,上下文菜单都不会关闭。

我尝试过寻找工作,但据我所知,没有办法以编程方式关闭上下文菜单。

非常感谢任何帮助。以下是用于打开上下文菜单和菜单项单击事件的单击事件的副本。

private void DataGridView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        DataGridView dgv = (DataGridView)sender;
        if (dgv.CurrentCell == null)
        {
            return;
        }
        else
        {
            Rectangle r = dgv.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false);
            Point p = new Point(r.X + e.X, r.Y + e.Y);
            ContextMenu cm = new ContextMenu();
            cm.MenuItems.Add(new MenuItem("Item", Item_Click));
            cm.Show(dgv, p);
        }
    }
}

private void Item_Click(object sender, EventArgs e)
{
    new SecondForm().Show();
}

更新: 我通过将ContextMenu类替换为ContextMenuStrip类,删除了MouseClick事件处理程序并将ContextMenuStrip对象分配给DataGridView.ContextMenuStrip来解决了这个问题。看起来好像ContextMenuStrip类在右键单击相关控件时处理显示菜单,所以如果你添加一个click事件处理程序来处理打开菜单,它会反复尝试渲染菜单,使它在它之前闪烁几次最终呈现

2 个答案:

答案 0 :(得分:0)

你班上的

添加私人变量

private bool CloseMenu = true;

鼠标按下上下文菜单

private void Item_Click(object sender, EventArgs e)
{
    CloseMenu = false;
    new SecondForm().Show();
}

添加上下文菜单结束事件

private void contextMenuStripMy_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
    e.Cancel = !CloseMenu;
    CloseMenu = true;
}

答案 1 :(得分:0)

经过多次试验,我发现了有关此问题的一些解决方法。

首先,这是关于ContextMenu而不是ContextMenuStrip。

这不是完美的解决方案,但是如果没有其他替代解决方案,它会很好用。

这是方法。

对于上下文菜单下的所有MenuItem,仅将Visiable设置为false。

唯一的问题是它在鼠标周围显示一个小方块。

我认为这个小方块是空的上下文菜单框。

但是,如果用户单击任意位置并且上下文菜单失去焦点,则将快速删除该小方块。

它真的很小,而且不会打扰。

在代码中,如果您只有一个菜单项,则外观类似于此。

                 if (cm != null)
                {
                    if (cm.MenuItems.Count > 0) cm.MenuItems[0].Visible = false;
                }

如果有多个项目,则只需循环浏览所有菜单项。

                 if (cm != null)
                {
                    for(int i = 0; i < cm.MenuItems.Count ; i++)
                     cm.MenuItems[i].Visible = false;
                }

希望这会有所帮助。

对我来说很有效。

所以我不必从ContextMenu切换到ContextMenuStrip。