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. Programming abstractions in C阅读笔记: p114-p117

    <Programming Abstractions in C>学习第48天,p114-p117,​总结如下: 一.技术总结 主要通过random number介绍了随机数的相关用法,int ...

  2. 音视频FAQ(一):视频直播卡顿

    一.摘要 本文介绍了视频直播卡顿的四个主要原因,用户网络问题.用户设备性能问题.技术路线的选择和实现问题.因本文主要阐述视频直播的卡顿,故技术路线的实现指的是:CDN供应商的实现问题,包含CDN性能不 ...

  3. 半导体行业通信标准SECS/GEM协议一看就懂的

    半导体行业通信标准SECS/GEM透析 HSMS通信的设备端通常为客户端(Equipment)(也可称为Active 在通信中主动连接对方的),工厂会部署服务端(Host)(也可称为Passive 被 ...

  4. 论文日记五:QueryInst

    导读 实例分割领域21年的SOTA,整个模型结构设计总述为以下: 1)设计了类似于Cascade Mask R-CNN的多阶段迭代优化的bbox和mask预测头: 2)基于query的实例分割方法,延 ...

  5. chatglm2-6b在P40上做LORA微调

    背景: 目前,大模型的技术应用已经遍地开花.最快的应用方式无非是利用自有垂直领域的数据进行模型微调.chatglm2-6b在国内开源的大模型上,效果比较突出.本文章分享的内容是用chatglm2-6b ...

  6. C静态库的创建与使用--为什么要引入静态库?

    C源程序需要经过预处理.编译.汇编几个阶段,得到各自源文件对应的可重定位目标文件,可重定位目标文件就是各个源文件的二进制机器代码,一般是.o格式.比如:util1.c.util2.c及main.c三个 ...

  7. python-显示张量(tensorflow)的具体的值

    ------------恢复内容开始------------ # 方法1 a = tf. random.normal ([4,4],mean=0.1,stddev=1) with tf.Session ...

  8. 14.9 Socket 高效文件传输

    网络上的文件传输功能也是很有必要实现一下的,网络传输文件的过程通常分为客户端和服务器端两部分.客户端可以选择上传或下载文件,将文件分块并逐块发送到服务器,或者从服务器分块地接收文件.服务器端接收来自客 ...

  9. android的listview控件,加了行内按钮事件导致行点击失效的问题

    近日,修改一个app,原来的listview中只有行点击事件 ListView.setOnItemClickListener(new AdapterView.OnItemClickListener() ...

  10. 创建vue项目并搭建JSONSERVER

    1.该前提是你已经搭建好vue-cli脚手架,开始创建一个新项目,输入 vue init webpack demo(demo是自定义项目名). 2.cd demo 进入项目安装依赖 3.在已经创建的项 ...