How do I correctly position a Context Menu when I right click a DataGridView's column header?

Here is a very simple way to make context menu appear where you right-click it.

Handle the event ColumnHeaderMouseClick

private void grid_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) 
{
  if (e.Button == System.Windows.Forms.MouseButtons.Right)
    contextMenuHeader.Show(Cursor.Position);
}

contextMenuHeader is a ContextMenuStrip that can be defined in the Designer view or at runtime.


To get the coordinate of the mouse cursor you could do this.

ContextMenu.Show(this, myDataGridView.PointToClient(Cursor.Position)); 

Have you tried using the Show overload that accepts a control and a position?

For example:

contextMenuStrip.Show(dataGrid, e.Location);

Edit: Full example

public partial class Form1 : Form
{
    DataGridView dataGrid;
    ContextMenuStrip contextMenuStrip;        

    public Form1()
    {
        InitializeComponent();

        dataGrid = new DataGridView();
        Controls.Add(dataGrid);
        dataGrid.Dock = System.Windows.Forms.DockStyle.Fill;
        dataGrid.MouseDown += MouseDown;
        dataGrid.DataSource = new Dictionary<string, string>().ToList();

        contextMenuStrip = new ContextMenuStrip();
        contextMenuStrip.Items.Add("foo");
        contextMenuStrip.Items.Add("bar");
    }

    private void MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Right)
        {
            if (dataGrid.HitTest(e.X, e.Y).Type == DataGridViewHitTestType.ColumnHeader)
            {
                contextMenuStrip.Show(dataGrid, e.Location);
            }
        }
    }
}

Tags:

C#

.Net

Winforms