DataGridView合并单元格,重绘后选中内容被覆盖的解决办法

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 }

猜你喜欢

转载自www.cnblogs.com/desertion/p/9173910.html
今日推荐