C# Winform 如何实现点击DataGridView按钮列时在按钮正下方显示右键菜单
原有代码问题
- 第一段代码问题:
- 未校验点击位置是否为目标按钮列,任意单元格点击都会触发菜单显示
- 菜单直接显示在鼠标点击坐标,而非按钮单元格正下方,位置不符合要求
- 未做可视区域空间判断,菜单超出屏幕时不会自动调整位置
- 第二段代码问题:
- 同样没有校验点击列是否为按钮列,触发范围不符合要求
- 位置计算取的是单元格右下角坐标,菜单会在按钮右下方而非正下方
- 依赖
CurrentCell获取单元格,当点击未选中的单元格时,CurrentCell未及时更新,会出现位置偏移 - 同样缺少空间不足时的位置调整逻辑
正确实现方案
推荐用CellContentClick事件替代MouseClick,可以精准捕获按钮点击事件,不需要手动做HitTest判断,实现步骤如下:
- 先确认你的按钮列的索引或者名称,示例中默认按钮列索引为3,你可以自行替换为实际的索引,或者用列名判断更稳妥
- 可以在设计器中绑定
dgList的CellContentClick事件,或者在Form_Load中添加绑定代码:dgList.CellContentClick += dgList_CellContentClick; - 事件实现代码如下:
private void dgList_CellContentClick(object sender, DataGridViewCellEventArgs e) { // 校验点击的是按钮列且是有效数据行(排除表头点击) // 此处可替换为列名判断:dgList.Columns[e.ColumnIndex].Name == "你的按钮列名" if (e.ColumnIndex != 3 || e.RowIndex < 0) return; // 获取点击的按钮单元格的显示区域 Rectangle cellRect = dgList.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false); // 计算按钮正下方的坐标(相对于DataGridView控件的坐标) Point showPoint = new Point(cellRect.Left, cellRect.Bottom); // 转换为屏幕坐标判断可视空间 Point screenPoint = dgList.PointToScreen(showPoint); int menuHeight = contextMenuStrip1.Height; Screen currentScreen = Screen.FromControl(dgList); int screenBottom = currentScreen.WorkingArea.Bottom; // 下方空间不足时,调整为显示在按钮上方 if (screenPoint.Y + menuHeight > screenBottom) { showPoint.Y = cellRect.Top - menuHeight; } // 可选:增加横向超出屏幕的适配逻辑 int menuWidth = contextMenuStrip1.Width; int screenRight = currentScreen.WorkingArea.Right; if (screenPoint.X + menuWidth > screenRight) { showPoint.X = screenRight - menuWidth - dgList.PointToScreen(Point.Empty).X; } // 显示菜单 contextMenuStrip1.Show(dgList, showPoint); }
内容的提问来源于stack exchange,提问作者Babu Goel
相关产品推荐
相关产品推荐

