DataGridView合并单元格只能进行重绘,网上基本上使用的是下面的方法:

 1 /// <summary>
2 /// 说明:纵向合并单元格
3 /// 参数:dgv DataGridView,e 绘制的单元格
4 /// </summary>
5 public void MergeCell(DataGridView dgv, DataGridViewCellPaintingEventArgs e)
6 {
7 int x = e.RowIndex, y = e.ColumnIndex;
8 using (Brush gridBrush = new SolidBrush(dgv.GridColor), backColorBrush = new SolidBrush(e.CellStyle.BackColor))
9 {
10 using (Pen gridLinePen = new Pen(gridBrush))
11 {
12 // 擦除原单元格
13 e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
14 ////绘制单元格相互间隔的区分线条, datagridview自己会处理左侧和上边缘的线条
15 bool b = false;
16 if (x == dgv.RowCount - 1)
17 b = true;
18 else
19 if (e.Value.ToString() != dgv.Rows[x + 1].Cells[y].Value.ToString())
20 b = true;
21 if (b)
22 {
23 //下边缘的线
24 e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
25 int fontheight = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Height;
26 int fontwidth = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Width;
27 int cellheight = e.CellBounds.Height;
28 int cellwidth = e.CellBounds.Width;
29 int countRows = 1; //计算合并单元格的总行数,以便内容可以居中显示
30 for (int i = x; i > 0; i--)
31 {
32 if (dgv.Rows[i - 1].Cells[y].Value.ToString() == e.Value.ToString())
33 countRows++;
34 else
35 break;
36 }
37 //绘制值
38 e.Graphics.DrawString(e.Value.ToString(), e.CellStyle.Font, Brushes.Black, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (countRows - 1) + (cellheight * countRows - fontheight) / 2, StringFormat.GenericDefault);
39 }
40 //右侧的线
41 e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1, e.CellBounds.Top, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
42 //设置处理事件完成(关键点),只有设置为ture,才能显示出想要的结果
43 e.Handled = true;
44 }
45 }
46 }

通过重绘可以达到合并单元格的目的,可是内容不居中很难看,居中的话又会出现点问题,如果选中重绘时擦除的单元格,内容会被覆盖,想了各种办法修改以上代码都无法解决。
最终另辟蹊径,不重绘单元格,而是新建Label覆盖到单元格上,达到合并单元格的假象,对DataGridView不作任何处理,这样就不会出现内容显示的问题了(唯一存在的问题就是合并的单元格无法被选中了),代码如下:

 1 /// <summary>
2 /// 说明:纵向合并单元格
3 /// 参数:dgv DataGridView,e 绘制的单元格
4 /// </summary>
5 public void MergeCell(DataGridView dgv, DataGridViewCellPaintingEventArgs e)
6 {
7 int x = e.RowIndex, y = e.ColumnIndex;
8 bool b = false;
9 if (x == dgv.RowCount - 1)
10 b = true;
11 else
12 if (e.Value.ToString() != dgv.Rows[x + 1].Cells[y].Value.ToString())
13 b = true;
14 if (b)
15 {
16 int countRows = 1;//合并单元格的总行数
17 for (int i = x; i > 0; i--)
18 {
19 if (dgv.Rows[i - 1].Cells[y].Value.ToString() == e.Value.ToString())
20 countRows++;
21 else
22 break;
23 }
24 Rectangle cell = e.CellBounds;
25 Label newLable = new Label();
26 newLable.BackColor = Color.White;
27 newLable.Height = cell.Height * countRows - 1;
28 newLable.Width = cell.Width - 1;
29 newLable.TextAlign = ContentAlignment.MiddleCenter;
30 newLable.Left = cell.X;
31 newLable.Top = cell.Y - (countRows - 1) * cell.Height;
32 newLable.Text = e.Value.ToString();
33 dgv.Controls.Add(newLable);
34 }
35 }

DataGridView合并单元格,重绘后选中内容被覆盖的解决办法的更多相关文章

  1. DataGridView合并单元格

    昨天一个同事问我DataGridView单元格合并的问题,一开始按照我的设想是算出两个单元格的Rectangle,然后直接使用e.Graphics.FillRectangle(backColorBru ...

  2. DataGridView合并单元格(一列或一行)

    #region"合并单元格的测试(一列或一行)" // int?是搜索一种类型(可空类型),普通的int不能为null,而用int?,其值可以为null //private int ...

  3. DataGridView合并单元格(多行多列合并)

    一.点击在拖入的显示控件(TreeList)右上方的箭头,在Treelist任务中选择数据源,添加项目数据源,依次选择数据库.数据集,新建连接,浏览选择数据库(*.mdb),依次点击 下一步,选择“表 ...

  4. [办公应用]如何将excel合并单元格分拆后每个单元格上仍保留数据?

    合并单元格虽然美观,但是无法进行排序.筛选等操作. 只有合并单元格拆分后才可以按常规进行统计.但是普通拆分后,excel仅保留合并单元格数据到区域左上角的单元格. 解决方案:选定多个合并单元格,应用本 ...

  5. sencha grid templatecolumn模板列,actioncolumn和renderer实现单元格重绘

    templatecolumn列: {                                     xtype: 'templatecolumn',                     ...

  6. Windows Forms DataGridView中合并单元格

    Windows Forms DataGridView 没有提供合并单元格的功能,要实现合并单元格的功能就要在CellPainting事件中使用Graphics.DrawLine和 Graphics.D ...

  7. JS动态生成表格后 合并单元格

    JS动态生成表格后 合并单元格 最近做项目碰到表格中的单元格合并的问题,需求是这样的,首先发ajax请求 请求回来后的数据 动态生成表格数据,但是生成后如果编号或者(根据其他的内容)有相同时,要合并单 ...

  8. datagridview 纵向 横向 合并单元格

    datagridview 单元格合并:纵向以及横向合并参考了csdn上不知哪位的代码,具体哪位找不到连接了. 纵向合并: /// <summary> /// 纵向合并,即合并数据项的值 / ...

  9. java poi 合并单元格后边框问题

    在项目中用poi合并单元格,但发现边框会有不显示的问题. 在网上搜集了答案,来记录一下. 解决方法: 将每个没用到的单元格都设空值. 例如: HSSFCell cell = row.createCel ...

  10. Qt高仿Excel表格组件-支持冻结列、冻结行、内容自适应和合并单元格

    目录 一.概述 二.效果展示 三.实现思路 1.冻结行.冻结列 2.行高自适应 3.蚂蚁线 四.测试代码 1.添加表格数据 2.设置冻结行.列 3.行高.列宽 4.单元格背景色 5.单元格文字 6.其 ...

随机推荐

  1. 使用LabVIEW 实现物体识别、图像分割、文字识别、人脸识别等深度视觉

    前言 哈喽,各位朋友们,这里是virobotics(仪酷智能),这两天有朋友私信问之前给大家介绍的工具包都可以实现什么功能,最新的一些模型能否使用工具包加载,今天就给大家介绍一下博主目前使用工具包已经 ...

  2. Matlab机器人工具箱安装教程

    参考以下博客 https://blog.csdn.net/AprilsHell/article/details/90722892

  3. 玩转 PI 系列-看起来像服务器的 ARM 开发板矩阵-Firefly Cluster Server

    前言 基于我个人的工作内容和兴趣,想要在家里搞一套服务器集群,用于容器/K8s 等方案的测试验证. 考虑过使用二手服务器,比如 Dell R730, 还搞了一套配置清单,如下: Dell R730 3 ...

  4. 遗传算法解决航路规划问题(MATLAB)

    遗传算法 文章部分图片和思路来自司守奎,孙兆亮<数学建模算法与应用>第二版 定义:遗传算法是一种基于自然选择原理和自然遗传机制的搜索(寻优)算法,模拟自然界中的声明进化机制,在人工系统中实 ...

  5. 面试官:说一下 MyBatis 缓存机制?

    MyBatis 的缓存机制属于本地缓存,适用于单机系统,它的作用是减少数据库的查询次数,提高系统性能. MyBaits 中包含两级本地缓存: 一级缓存:SqlSession 级别的,是 MyBatis ...

  6. MySQL-通过存储过程来添加和删除分区(List分区)

    1.背景原因 当前MySQL不支持在添加和删除分区时,使用IF NOT EXISTS和IF EXISTS.所以在执行调度任务时,直接通过ADD PARTITION和DROP PARTITION不可避免 ...

  7. window操作系统安装多个版本nodejs版本-控制工具nvm

    参考: https://blog.csdn.net/m0_38134431/article/details/118388297 https://juejin.cn/post/7044890876631 ...

  8. golang .(type)语法

    一直弄不懂 .(type) 是啥,在 liteide 中输出 (1+1).(type),提示: use of .(type) outside type switch 于是搜索到这个文章: 作者:翔云翔 ...

  9. proto转java类时相关option配置

    转载请注明出处: option java_multiple_files = true; 作用和意义:此选项指示生成的 Java 代码将被分割成多个文件而不是一个文件.每个消息类型都会生成一个单独的 J ...

  10. umich cv-1

    UMICH CV Image Classification---KNN 在本节课中,首先justin老师为我们介绍了图像分类了基础概念以及其用途,这里就不多涉及了 接着我们思考图像分类问题,如果我们想 ...