单击datagrid的空白部分时,防止出现上下文菜单

时间:2012-03-14 19:53:32

标签: c# datagridview

在C#中右键单击DataGridView的空白部分(单击不包含任何行的网格的一部分)时,上下文菜单仍会显示其基于行的选项。如果点击落在一行上,我怎么才能显示上下文菜单?

据我所知:

    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?
                }
            }

    }

我正在以编程方式构建Datagrid和上下文菜单,如下所示:

                    //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);

2 个答案:

答案 0 :(得分:11)

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

答案 1 :(得分:0)

这不是我的解决方案,但我得到了类似问题的解决方案......感谢 DarkSquirrel42 的答案! :)

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