如何判断DataGridView鼠标事件发生在行分隔条还是行本身
检测DataGridView行分隔条的点击与拖拽事件
因为DataGridView.HitTestInfo本身不支持直接识别DividerHeight对应的分隔区域,你可以通过手动计算鼠标坐标与行分隔条的位置范围来实现检测,具体方案如下:
核心思路
行分隔条是附加在目标行底部的区域,范围为:[行顶部 + 行高度, 行顶部 + 行高度 + 行DividerHeight]。通过对比鼠标坐标是否落在这个区间内,即可判断是否命中分隔条。
点击事件检测示例
在MouseDown事件中实现判断逻辑:
private void dataGridView1_MouseDown(object sender, MouseEventArgs e) { var dgv = sender as DataGridView; var hitTestResult = dgv.HitTest(e.X, e.Y); // 仅处理命中行相关区域的情况 if (hitTestResult.Type is DataGridViewHitTestType.Cell or DataGridViewHitTestType.RowHeader) { var targetRow = dgv.Rows[hitTestResult.RowIndex]; // 计算分隔条的上下边界 int dividerTop = targetRow.Top + targetRow.Height; int dividerBottom = dividerTop + targetRow.DividerHeight; if (e.Y >= dividerTop && e.Y <= dividerBottom && targetRow.DividerHeight > 0) { // 此处编写分隔条被点击的业务逻辑 Console.WriteLine($"触发行{hitTestResult.RowIndex}的分隔条点击事件"); } else { // 此处编写行主体区域被点击的业务逻辑 } } }
拖拽事件检测示例
在DragEnter或DragOver事件中,先将屏幕坐标转换为控件内坐标,再执行同样的范围判断:
private void dataGridView1_DragEnter(object sender, DragEventArgs e) { var dgv = sender as DataGridView; // 转换拖拽坐标为DataGridView内部坐标 Point clientPoint = dgv.PointToClient(new Point(e.X, e.Y)); var hitTestResult = dgv.HitTest(clientPoint.X, clientPoint.Y); if (hitTestResult.Type is DataGridViewHitTestType.Cell or DataGridViewHitTestType.RowHeader) { var targetRow = dgv.Rows[hitTestResult.RowIndex]; int dividerTop = targetRow.Top + targetRow.Height; int dividerBottom = dividerTop + targetRow.DividerHeight; if (clientPoint.Y >= dividerTop && clientPoint.Y <= dividerBottom && targetRow.DividerHeight > 0) { e.Effect = DragDropEffects.Move; // 根据需求设置拖拽效果 // 此处编写拖拽到分隔条的业务逻辑 } else { e.Effect = DragDropEffects.None; // 此处编写拖拽到行主体区域的业务逻辑 } } }
注意事项
- 必须判断
targetRow.DividerHeight > 0,避免无效的范围计算 - 该逻辑自动适配滚动条偏移,因为
Row.Top属性已经包含了滚动后的位置偏移
内容的提问来源于stack exchange,提问作者denideni21
相关产品推荐
相关产品推荐

