0

In my application I want that every time someone presses right click on a DataGridView cell, it will open a menu window. Something like that:
enter image description here

The menu should disappear when you move the mouse and click on any place in the WinForm.

This is what I did in the beginning but after couple of seconds it threws an error "Cross-thread operation not valid:

private FormRightClickGridViewMenu m_RightClickMenuOnGridView = new FormRightClickGridViewMenu();
private Thread m_RightClickMenuOnGridViewThread;
        
private void openRightClickMenuOnGridView(int i_X, int i_Y)
{
    if (!m_RightClickMenuOnGridView.Visible)
    {
        m_RightClickMenuOnGridView.Location = new Point(i_X, i_Y);
        m_RightClickMenuOnGridView.ShowDialog();
    }
}

private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Right)
    {
        m_RightClickMenuOnGridViewThread = new Thread(() => openRightClickMenuOnGridView(((DataGridView)sender).Location.X, ((DataGridView)sender).Location.Y));
        m_RightClickMenuOnGridViewThread.Start();

    }
    else
    {
        m_RightClickMenuOnGridView.Close();
        m_RightClickMenuOnGridViewThread.Abort();
    }
}  

I tried to fix it by creating this new code with delegate but now the menu Window is open and you cann't get to the other main WinForm, it waits for closing it.

private FormRightClickGridViewMenu m_RightClickMenuOnGridView = new FormRightClickGridViewMenu();
private Thread m_RightClickMenuOnGridViewThread;

private delegate void openRightClickMenuOnGridViewCallBack(int i_X, int i_Y);
private void openRightClickMenuOnGridView(int i_X, int i_Y)
{
    if (this.InvokeRequired)
    {
        openRightClickMenuOnGridViewCallBack s = new openRightClickMenuOnGridViewCallBack(openRightClickMenuOnGridView);
        this.Invoke(s, i_X, i_Y);
    }
    else
    {
        if (!m_RightClickMenuOnGridView.Visible)
        {
            m_RightClickMenuOnGridView.Location = new Point(i_X, i_Y);
            m_RightClickMenuOnGridView.ShowDialog();
        }

    }
} 

private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Right)
    {
        ThreadPool.QueueUserWorkItem(o => openRightClickMenuOnGridView(((DataGridView)sender).Location.X, ((DataGridView)sender).Location.Y));
    }
    else
    {
        m_RightClickMenuOnGridView.Close();
        m_RightClickMenuOnGridViewThread.Abort();
    }
}

To sum it up, I want to press right click on a DataGridView cell, open a window like in the picture and when someone click with the mouse in other place on the DataGridView, it will close that menu.

E235
  • 11,560
  • 24
  • 91
  • 141
  • 1
    `DataGridViewCell` has a [`ContextMenuStrip` property](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.datagridviewcell.contextmenustrip). Is there some reason you can't just assign a context menu to the cells? – Joshua Robinson Mar 14 '22 at 14:17
  • 1
    @JoshuaRobinson thanks! I wasn't familiar with this ContextMenu. I follow this answer https://stackoverflow.com/a/47897850/2153777 to do it, it seems to work good – E235 Mar 14 '22 at 14:43

0 Answers0