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

atw*_*pub 4 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?
                }
            }

    }
Run Code Online (Sandbox Code Playgroud)

我以编程方式构建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);
Run Code Online (Sandbox Code Playgroud)

Dar*_*l42 12

那个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;
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)