C#如何为DataGridView的两个鼠标事件复用处理函数?
这问题我之前做WinForms开发时也碰到过,核心就是要绕开两个事件参数类型不同的限制,把重复逻辑抽出来复用。给你两个实用的解决方案:
方案一:利用参数的继承关系
其实DataGridViewCellMouseEventArgs是DataGridViewCellEventArgs的子类,它完全包含父类的所有属性(ColumnIndex、RowIndex)。所以我们可以把共用逻辑封装成一个接受DataGridViewCellEventArgs参数的方法,然后在两个事件处理函数里直接传递参数就行:
// 抽离的共用逻辑方法 private void ProcessLink(DataGridViewCellEventArgs e) { // 用模式匹配简化类型判断,同时获取linkCell实例 if (e.ColumnIndex >= 0 && e.RowIndex >= 0 && dgv.Rows[e.RowIndex].Cells[e.ColumnIndex] is DataGridViewLinkCell linkCell) { // 增加URL有效性校验,避免无效字符串导致报错 if (Uri.TryCreate(linkCell.Value as string, UriKind.Absolute, out Uri? targetUri)) { // 针对.NET Core/.NET 5+,建议用带ProcessStartInfo的重载,避免平台兼容性问题 Process.Start(new ProcessStartInfo(targetUri.ToString()) { UseShellExecute = true }); } } } // 修改后的CellContentClick事件 private void dgv_CellContentClick(object sender, DataGridViewCellEventArgs e) { ProcessLink(e); } // 修改后的ColumnHeaderMouseClick事件 private void dgv_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) { // 直接传递e,子类可以隐式转换为父类类型 ProcessLink(e); }
方案二:提取关键索引参数(更通用)
如果以后需要适配更多不同参数类型的事件,或者不想依赖继承关系,我们可以直接把需要的ColumnIndex和RowIndex作为参数抽离出来,这样不管参数类型是什么,只要能拿到这两个值就能调用:
// 抽离的共用逻辑方法 private void ProcessLink(int columnIndex, int rowIndex) { if (columnIndex >= 0 && rowIndex >= 0 && dgv.Rows[rowIndex].Cells[columnIndex] is DataGridViewLinkCell linkCell) { if (Uri.TryCreate(linkCell.Value as string, UriKind.Absolute, out Uri? targetUri)) { Process.Start(new ProcessStartInfo(targetUri.ToString()) { UseShellExecute = true }); } } } // 修改后的CellContentClick事件 private void dgv_CellContentClick(object sender, DataGridViewCellEventArgs e) { ProcessLink(e.ColumnIndex, e.RowIndex); } // 修改后的ColumnHeaderMouseClick事件 private void dgv_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) { ProcessLink(e.ColumnIndex, e.RowIndex); }
额外提示
原代码里直接调用Process.Start(linkValue)在.NET Core及以后的版本可能会有平台兼容性问题,建议改用带ProcessStartInfo的重载并设置UseShellExecute = true,同时增加URL有效性校验,避免传入无效字符串导致程序崩溃。
内容的提问来源于stack exchange,提问作者M. Raul
相关产品推荐
相关产品推荐

