Prevent display of context menu when clicking on empty part of datagrid
When right clicking on an empty part of the DataGridView in C # (clicking on the part of the grid that does not contain rows) the context menu still appears with row based options. How can I only display the context menu when a click falls on a row?
This is how I understood it:
private void f_context_select_row(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
var hti = jobs_datagrid.HitTest(e.X, e.Y);
if (hti.RowIndex >= 0)
{
jobs_datagrid.ClearSelection();
jobs_datagrid.Rows[hti.RowIndex].Selected = true;
}
else
{
//what can I do here to collapse the context menu?
}
}
}
I am creating Datagrid and context menu programmatically like this:
//on right click select row
jobs_datagrid.MouseDown += new MouseEventHandler(f_context_select_row);
//generate context menu
ContextMenuStrip m = new ContextMenuStrip();
ToolStripMenuItem context_datagrid_run = new ToolStripMenuItem("Run All Selected Campaigns");
ToolStripMenuItem context_datagrid_edit = new ToolStripMenuItem("Edit This Campaign");
ToolStripMenuItem context_datagrid_delete = new ToolStripMenuItem("Delete This Campaign");
context_datagrid_delete.Click += f_context_datagrid_delete;
context_datagrid_run.Click += f_run_selected_campaigns;
context_datagrid_edit.Click += f_context_datagrid_edit;
m.Items.Add(context_datagrid_delete);
m.Items.Add(context_datagrid_run);
m.Items.Add(context_datagrid_edit);
jobs_datagrid.ContextMenuStrip = m;
splitContainer3.Panel2.Controls.Add(jobs_datagrid);
+3
source to share
2 answers
how about an event ContextMenuStrip.Opening
?
private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
{
var cms = sender as ContextMenuStrip;
var mousepos = Control.MousePosition;
if (cms != null)
{
var rel_mousePos = cms.PointToClient(mousepos);
if (cms.ClientRectangle.Contains(rel_mousePos))
{
//the mouse pos is on the menu ...
//looks like the mouse was used to open it
var dgv_rel_mousePos = dataGridView1.PointToClient(mousepos);
var hti = dataGridView1.HitTest(dgv_rel_mousePos.X, dgv_rel_mousePos.Y);
if (hti.RowIndex == -1)
{
// no row ...
e.Cancel = true;
}
}
else
{
//looks like the menu was opened without the mouse ...
//we could cancel the menu, or perhaps use the currently selected cell as reference...
e.Cancel = true;
}
}
}
+8
source to share
This is not my solution, but I got a solution to a similar problem ... thanks to DarkSquirrel42's answer ! :)
/// <summary>
/// Evento que permite ubicar la posicion del mouse y muestra el menu contextual.
/// </summary>
private void dgw_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
/*Obtener y seleccion celda donde se hizo el click*/
DataGridView.HitTestInfo _htInfo = dgw.HitTest(e.X, e.Y);
dgw.CurrentCell = dgw[_htInfo.ColumnIndex, _htInfo.RowIndex];
//Invocar evento de apertura de Menu Contextual donde se ocultara si la celda es de lectura,
//O se mostrara si la celda es de edicion.
dgw.ContextMenuStrip.Opening += (s, i) =>
{
if (dgw.CurrentCell.ReadOnly)
i.Cancel = true;//Evita que se muestre el Menu Contextual
else
{
i.Cancel = false;//Permite que se muestre el Menu Contextual
ContextMenu.Show(dgw, new Point(e.X, e.Y));
}
};
}
}
0
source to share