在我的应用程序中,我有DataGridView
用于配置某些选项。我们的想法是您可以在第一列中输入您想要的任何文本,但如果您右键单击它将为您提供明确支持的值。我需要将它作为文本框而不是下拉列表,因为我需要支持编辑无效(或旧)配置。
我想要的是用户右键单击字段名称列,并根据这种配置类型设置有效的上下文菜单。因此,我编写了以下事件
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);
}
}
}
这可以“正确”工作,但上下文菜单显示在表单的顶部,而不是鼠标指针所在的位置。如果我更改Show()
调用以使用DataGridView
而不是表单,我会遇到相同的问题,但它出现在网格的左上角,而不是鼠标所在的位置。< / p>
奇怪的是,如果我将此事件更改为MouseClick
事件(而不是CellMouseclick
事件),一切正常并且上下文菜单恰好出现在鼠标指针所在的位置。此选项的问题是用户可能没有右键单击当前选定的单元格,这意味着当他们单击菜单项时,将更改所选单元格而不是他们右键单击的单元格。
有没有人有任何提示为什么使用CellMouseClick
创建的上下文菜单没有显示在正确的位置?
答案 0 :(得分:19)
menu.Show(this, e.Location, LeftRightAlignment.Right);
第二个参数是鼠标位置,相对于单元格的左上角。在编程时,您将相对于 this (表单)进行相对偏移,这将使菜单显示在表单的左上角。使用DGV作为第一个参数也不起作用,现在它位于网格的左上角。
有几种方法可以解决这个问题,但这很简单:
Point pos = this.PointToClient(Cursor.Position);
menu.Show(this, pos, LeftRightAlignment.Right);
您可以随意使用grvFieldData替换 this 。
答案 1 :(得分:3)
在datagridview鼠标点击事件中:
if e.button= mousebutton.right
{
contextmenu1.Show(MousePosition);
}
答案 2 :(得分:1)
尝试使用PointToClient
获取正确的位置
答案 3 :(得分:1)
它没有显示在正确的位置,因为e.Location是相对于父对象左上角的位置,在这种情况下是单元格本身。位置属性始终与其容器相关。
要获取鼠标光标相对于表单左上角的位置,可以使用
this.PointToClient(Cursor.Position);
答案 4 :(得分:1)
我已经解决了这个问题......有人觉得这个方法很奇怪,但它运行正常!) 如果我们想在datagridview单元格中按右键btn同时看到上下文菜单,而不是在屏幕中间或其他地方,我们需要:
制作一些变量
int x=0;
int y=0;
为datagridview1制作一个'MouseMove'事件:
private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
{
x = e.X;
y = e.Y;
}
和
private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
contextMenuStrip1.Show(dataGridView1, x,y);
}
}
您的欢迎