C# DataGridView 在右键单击的位置打开 ContextMenu

C# DataGridView opening ContextMenu at location of Right Click

我已经四处寻找了很长一段时间,试图找到一个可行的解决方案,但我求助于一个问题:

我的应用程序的对话框窗体中有一个 DataGridView,我希望在右键单击单元格时显示上下文菜单。

我有右键单击和 ContextMenu 显示正常,但是无论我在 StackExchange 上尝试什么解决方案,它总是偏移很多。

这与它的父表单and/or有关吗?还是我只是在这里愚蠢地遗漏了什么?

谢谢 杰米

Form.cs

private void dataGridContents_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        if (e.RowIndex > -1 && e.ColumnIndex > -1)
        {
            Debug.WriteLine("Cell right clicked!");

            DataGridViewCell cell = (sender as DataGridView)[e.ColumnIndex, e.RowIndex];

            contextCell.Show(cell.DataGridView, PointToClient(Cursor.Position));

            if (!cell.Selected)
            {
                cell.DataGridView.ClearSelection();
                cell.DataGridView.CurrentCell = cell;
                cell.Selected = true;
            }
        }
    }
}

编辑

对不起,我试过了:

可能还有其他一些人。

编辑 2

这就是我所说的偏移量——一些解决方案导致此偏移量在一定幅度内变化(有些非常遥远等)——但所有解决方案都像实际光标的偏移量一样。

编辑 3

我的contextCellnew ContextMenu()

选项 1: 显示行上下文菜单的最简单解决方案是将上下文菜单分配给 DataGridView 的 RowTemplate.ContextMenuStrip 属性:

dataGridView1.RowTemplate.ContextMenuStrip = contextMenuStrip1;

选项 2: 此外,如果您想 select 在显示 ContextMenuStrip 之前的单元格,它足以处理 CellContextMenuStripNeeded 事件:

private void dataGridView1_CellContextMenuStripNeeded(object sender,
    DataGridViewCellContextMenuStripNeededEventArgs e)
{
    if (e.RowIndex > -1 && e.ColumnIndex > -1)
    {
        dataGridView1.CurrentCell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
        e.ContextMenuStrip = contextMenuStrip1;
    }
}

你犯了什么错误?

您计算鼠标在 DataGridView 上的位置有误。您正在使用 PointToClient 表示 this.PointToClient,而您需要使用 DataGridView 的方法,例如 dataGridView1.PointToClient:

myContextMenu.Show(dataGridView1,dataGridView1.PointToClient(Cursor.Position));

仅供参考,您可以使用此代码简单地显示 ContextMenu,无需使用 ContextMenuStrip

但我强烈建议您使用ContextMenuStrip

答案是让 contextCell 变成 ContextMenuStrip 而不是原来的 ContextMenu

毕竟......

感谢您的回复。

this.dataGridView1.ContextMenuStrip = this.contextMenuStrip1;

并处理 DataGridView.CellContextMenuStripNeeded Event