Why is my WinForms context menu not showing where the mouse is?

In my application, I have a DataGridView that is designed to configure some parameters. The idea is that you can enter any text you want in the first column, but if you right-click, you will get explicitly supported values. I need this text box, not a drop-down list, because I need to support editing invalid (or old) configurations.

I want the user to right-click in the Field Name column and has a context menu that is valid depending on the type of configuration. So I coded the following event

  private void grvFieldData_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e) { // If this is a right click on the Field name column, create a context menu // with recognized options for that field if (e.Button == MouseButtons.Right && grvFieldData.Columns[e.ColumnIndex].Name == "clmFieldName") { ContextMenu menu = new ContextMenu(); if (_supportedDataGrids.ContainsKey((cmbDataGrid.SelectedItem as DataGridFieldList).GridName)) { // Loop through all the fields and add them to the context menu List<string> fields = _supportedDataGrids[((cmbDataGrid.SelectedItem as DataGridFieldList).GridName)]; fields.Sort(); foreach (string field in fields) menu.MenuItems.Add(new MenuItem(field)); // Make sure there is at least one field before displaying the context menu if (menu.MenuItems.Count > 0) menu.Show(this, e.Location, LeftRightAlignment.Right); } } } 

This works β€œcorrectly”, but the context menu appears at the top of the form, and not where the mouse pointer is. If I modify the Show() call to use a DataGridView instead of a form, I have the same problem, but instead it appears in the upper left corner of the grid, and not where the mouse is.

Oddly enough, if I changed this event to the MouseClick event (instead of the CellMouseclick event), everything will work, and the context menu will be displayed exactly where the mouse pointer is. The problem with this option is that the user may not right-click on the selected cell, which means that when you click on a menu item, the selected cell will be changed, and not the cell that they clicked on.

Does anyone have any clues why context menus created using CellMouseclick do not appear in the right place?

+6
c # winforms contextmenu
source share
5 answers
  menu.Show(this, e.Location, LeftRightAlignment.Right); 

The second argument is the location of the mouse relative to the upper left corner of the cell. As programmed, you make this offset relative to this, a form that will make the menu appear in the upper left corner of the form. Use DGV since the first argument does not work, now it is in the upper left corner of the grid.

A few ways to fix this, but this is an easy way:

  Point pos = this.PointToClient(Cursor.Position); menu.Show(this, pos, LeftRightAlignment.Right); 

You can optionally replace this with grvFieldData.

+17
source share

In the clickatridview mouse event:

 if e.button= mousebutton.right { contextmenu1.Show(MousePosition); } 
+3
source share

try using PointToClient to get the right place

+1
source share

It does not appear in the right place, because e.Location is the location relative to the upper left corner of the parent object, which in this case is the cell itself. Location properties always refer to their container.

To get the position of the mouse cursor relative to the upper left corner of the form, you can use

 this.PointToClient(Cursor.Position); 
+1
source share

I solved this problem ... they might find this method weird, but it works great!) If we want to see the context menu by clicking the btn right mouse button in the datagridview cell, and right there, not in the middle of the screen or somewhere else, we need:

make some variables

 int x=0; int y=0; 

make the "MouseMove" event for datagridview1 lke, which:

 private void dataGridView1_MouseMove(object sender, MouseEventArgs e) { x = eX; y = eY; } 

and

 private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Right) { contextMenuStrip1.Show(dataGridView1, x,y); } } 

Your greeting

+1
source share

All Articles