简体   繁体   中英

WinForms ContextMenu stays open when MenuItem is clicked

So I have a form DataGridView and when I right click on the grid I want to display a context menu that has one menu item in it. The menu item will open a second form that will provide some configuration options for the DataGridView.

Now all of this works absolutely fine, the context menu displays correctly and the second form opens correctly and all of the functionality on that form works correctly.

The only issue is that the context menu will only close if I click anywhere other than the menu item. No matter how many times I click on the menu item the context menu does not close.

I have tried looking for work arounds but as far as I can tell there is no way to programatically close the context menu.

Any help would be greatly appreciated. Below are copies of the click events for opening the context menu and for the menu item click event.

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

UPDATE: I solved the issue by replacing the ContextMenu class with the ContextMenuStrip class, removing the MouseClick event handler and assigning the ContextMenuStrip object to DataGridView.ContextMenuStrip. It appears as though the ContextMenuStrip class deals with showing the menu when it's relevant control is right clicked, so if you add a click event handler to deal with opening the menu it will repeatedly try to render the menu making it flicker several times before it is eventually rendered

in your class add a private variable

private bool CloseMenu = true;

on mouse down of your Context Menu

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

add context menu closing event

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

I found some workdaround on this problem after many trials.

Firstly, this is about ContextMenu and not ContextMenuStrip.

This is not perfect solution but it works good if you do not have other alternative solution.

Here is how.

Just Set Visiable = false for all MenuItems under the Context Menu.

Only one problem with this is that it shows small square around the mouse.

I think this small square is the empty context menu box.

However, this small square will be removed quickly if user clicks anywhere and if the context menu lose focus.

It is really small and not bothering.

In code, this will look something like this in case you have only one menu item.

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

If you have multiple of items, then just loop through all menu items.

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

Hope this helps.

It worked for my case.

So I did not have to swtich to ContextMenuStrip from ContextMenu.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM