昨天一个同事问我DataGridView单元格合并的问题,一开始按照我的设想是算出两个单元格的Rectangle,
然后直接使用e.Graphics.FillRectangle(backColorBrush, rectangle)从新填充下背景色,然后在绘制显示的字符,当然这种想法是行不通的。

下面是我写的一个单元格合并的方法,其实这种方法并不好,只是看上去是把单元格合并了,其实实际DataGridView的列结构是没有发生变化,而且这种重绘的方法并不能编辑,所以我还是建议如果遇到合并单元格的问题,最好还是不要用DataGridView
如有不懂得可以加(源码分享群 81582487)一起交流
代码部分:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsDemo
{
    public partial class DataGridViewMergeCell : Form
    {
        public DataGridViewMergeCell()
        {
            InitializeComponent();
            Init();
        }

private void DataGridViewMergeCell_Load(object sender, EventArgs e)
        {
            int rowIndex = view.Rows.Add();
            DataGridViewRow row = view.Rows[rowIndex];
            row.Cells["value"].Value = "bbb";
            row.Cells["name"].Value = "aaa";
            row.Cells["price"].Value = "bbb";
            row.Cells["num"].Value = "aaa";
            rowIndex = view.Rows.Add();
            row = view.Rows[rowIndex];
            row.Cells["value"].Value = "bbb";
            row.Cells["name"].Value = "aaa";
            row.Cells["price"].Value = "bbb";
            row.Cells["num"].Value = "aaa";
            rowIndex = view.Rows.Add();
            row = view.Rows[rowIndex];
            row.Cells["value"].Value = "bbb";
            row.Cells["name"].Value = "aaa";
            row.Cells["price"].Value = "bbb";
            row.Cells["num"].Value = "aaa";
            rowIndex = view.Rows.Add();
            row = view.Rows[rowIndex];
            row.Cells["value"].Value = "bbb";
            row.Cells["name"].Value = "aaa";
            row.Cells["price"].Value = "bbb";
            row.Cells["num"].Value = "aaa";
            rowIndex = view.Rows.Add();
            row = view.Rows[rowIndex];
            row.Cells["value"].Value = "bbb";
            row.Cells["name"].Value = "aaa";
            row.Cells["price"].Value = "bbb";
            row.Cells["num"].Value = "aaa";
           
           
        }

private void Init() {

view.AllowUserToAddRows = false;
            // view.ColumnHeadersVisible = false;
            view.AutoGenerateColumns = false;
            view.AutoSize = false;
            //view.RowHeadersVisible = false;
            //view.GridColor = System.Drawing.ColorTranslator.FromHtml("#F8F8FF");
            view.ColumnHeadersHeight = 60;
           
            view.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
            view.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
            view.Columns.Add(new DataGridViewTextBoxColumn() { Name = "name", HeaderText = "主体", Width = 90, ReadOnly = true,Visible = true, AutoSizeMode = DataGridViewAutoSizeColumnMode.None });
            view.Columns.Add(new DataGridViewTextBoxColumn() { Name = "value", HeaderText = "", Width = 80, ReadOnly = true, Visible = true, AutoSizeMode = DataGridViewAutoSizeColumnMode.None });
            view.Columns.Add(new DataGridViewTextBoxColumn() { Name = "price", HeaderText = "主体", Width = 90, ReadOnly = true, Visible = true, AutoSizeMode = DataGridViewAutoSizeColumnMode.None });
            view.Columns.Add(new DataGridViewTextBoxColumn() { Name = "num", HeaderText = "", Width = 80, ReadOnly = true, Visible = true, AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill });
            view.CellPainting -= new DataGridViewCellPaintingEventHandler(view_CellPainting);
            view.CellPainting += new DataGridViewCellPaintingEventHandler(view_CellPainting);
        }

void view_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.RowIndex == 1 && e.ColumnIndex == 1)
            {
                Brush backColorBrush = new SolidBrush(e.CellStyle.BackColor);
                e.Paint(e.CellBounds, DataGridViewPaintParts.All);
                e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
                //绘制背景色(被选中状态下)  
                if (e.State == (DataGridViewElementStates.Displayed | DataGridViewElementStates.Selected | DataGridViewElementStates.Visible))
                    e.PaintBackground(e.CellBounds, false);
                //分别绘制原文本和现在改变颜色的文本  
                Brush fontColor = new SolidBrush(e.CellStyle.ForeColor);
                // e.Graphics.DrawString("", this.Font, fontColor, e.CellBounds, StringFormat.GenericDefault);
                //绘制下边框线
                Brush gridBrush = new SolidBrush(this.view.GridColor);
                Pen pen = new Pen(gridBrush);
                e.Graphics.DrawLine(pen, e.CellBounds.Left, e.CellBounds.Bottom - 1,
                          e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
              DataGridViewCell cell =  this.view.Rows[e.RowIndex].Cells[e.ColumnIndex];
                
              cell.Value = "";
              e.Handled = true;
            }
            if (e.RowIndex == 1 && e.ColumnIndex == 2)
            {
                Brush backColorBrush = new SolidBrush(e.CellStyle.BackColor);
                e.Paint(e.CellBounds, DataGridViewPaintParts.All);
                e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
                //绘制背景色(被选中状态下)  
                if (e.State == (DataGridViewElementStates.Displayed | DataGridViewElementStates.Selected | DataGridViewElementStates.Visible))
                    e.PaintBackground(e.CellBounds, true);
                //分别绘制原文本和现在改变颜色的文本  
                Brush fontColor = new SolidBrush(e.CellStyle.ForeColor);
               // e.Graphics.DrawString("", this.Font, fontColor, e.CellBounds, StringFormat.GenericDefault);
                //绘制下边框线
                Brush gridBrush = new SolidBrush(this.view.GridColor);
                Pen pen = new Pen(gridBrush);

e.Graphics.DrawLine(pen, e.CellBounds.Left, e.CellBounds.Bottom - 1,
                          e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);

//绘制右边框线
                e.Graphics.DrawLine(pen, e.CellBounds.Right - 1,
                           e.CellBounds.Top, e.CellBounds.Right - 1,
                           e.CellBounds.Bottom - 1);
                DataGridViewCell cell = this.view.Rows[e.RowIndex].Cells[e.ColumnIndex];
                cell.Value = "";
                cell.Tag = "ccccc";
                Rectangle rectanle = e.CellBounds;
                rectanle.X = rectanle.X -15;
                rectanle.Y = rectanle.Y + 5;
                //这里需要注意的是我没有用 e.Graphics 原因是这个只能在当前单元格绘制
                //而我是在DataGridView上面建一个绘图Graphics对象这样就可以看上去在两个单元格里面绘制了
                //这里你们也可以自己试一试
                Graphics graphics = this.view.CreateGraphics();
                //分别绘制原文本和现在改变颜色的文本  
                graphics.DrawString("cccc", this.Font, new SolidBrush(e.CellStyle.ForeColor), rectanle, StringFormat.GenericDefault);
                e.Handled = true;
            }
        }
    }
}

以下是我的建议,这种虽然看上去是把问题解决了,其实这样有很多缺点,一个是不能编辑,而且这个还有个bug就是点击左边的边框的时候会把左边的文字隐藏起来,我试了很多方法都没解决,这个应该是编辑的时候背景颜色给遮住了。

一下推荐一个可以合并单元格的第三方控件(DevExpress.XtraGrid.v7.3.dll),这个现在我也没有研究,不过后续我会研究的,也会在写篇文章的

DataGridView合并单元格的更多相关文章

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

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

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

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

  3. Windows Forms DataGridView中合并单元格

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

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

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

  5. NPOI_winfrom导出Excel表格(一)(合并单元格、规定范围加外边框、存储路径弹框选择)

    1.导出 private void btn_print_Click(object sender, EventArgs e) { DataTable dtNew = new DataTable(); d ...

  6. C# 获取Excel中的合并单元格

    C# 获取Excel中的合并单元格 我们在制作表格时,有时经常需要合并及取消合并一些单元格.在取消合并单元格时需要逐个查找及取消,比较麻烦.这里分享一个简单的方法来识别Excel中的合并单元格,识别这 ...

  7. jquery操作表格 合并单元格

    jquery操作table,合并单元格,合并相同的行 合并的方法 $("#tableid").mergeCell({ cols:[X,X] ///参数为要合并的列}) /** * ...

  8. NPOI操作EXCEL(五)——含合并单元格复杂表头的EXCEL解析

    我们在第三篇文章中谈到了那些非常反人类的excel模板,博主为了养家糊口,也玩命做出了相应的解析方法... 我们先来看看第一类复杂表头: ...... 博主称这类excel模板为略复杂表头模板(蓝色部 ...

  9. poi获取合并单元格内的第一行第一列的值

    当读取如图所示的excel时,显示为第1行 第1列 的内容是:合并单元格 其它在合并单元格区域内的单元格不显示 示例代码如下: import java.io.FileInputStream; impo ...

随机推荐

  1. IIS启动网站出错的几个解决方法

    在ASP.NET项目中使用了IIS服务器,由于系统是XP的,而在装系统的时候IIS没有一起装,所以从网上下载的IIS5.0版本(其它版本XP是用不了的).但是在使用的过程中老是出问题,每次调试好后,过 ...

  2. 【循序渐进学Python】2. Python中的序列——列表和元组

    序列概览 在Python中有六种内建的序列:列表.元组.字符串.Unicode字符串.buffer对象和xrange对象.在这里暂时只讨论列表和元组.列表和元组的主要区别在于:列表可以修改,元组(不可 ...

  3. document.documentElement.clientWidth

    document.documentElement.clientWidth 摘自:http://blog.sina.com.cn/s/blog_6f1f9ead0100n1f6.html 关于获取各种浏 ...

  4. (转) 关于在IE6下 无法跳转问题

    之前在项目,用到超链接,在ie下没有问题,但是到了ie6,居然发现点击事件不起作用, 真不可思议,以前都没注意到,后来网上搜了下,问题就出在这个void(0)上!现把网上的资料整理了下. <a  ...

  5. [PE结构分析] 7.相对虚拟地址(RVA)和文件偏移间的转换

    RVA是相对虚拟地址(Relative Virtual Address)的缩写.RVA是当PE 文件被装载到内存中后,某个数据位置相对于文件头的偏移量. 例如:导入表的位置和大小可以从PE文件头中IM ...

  6. 打印机问题win7 和xp

    服务器端问题,重启如下服务 net stop "print spooler" net start "print spooler" gpedit.msc 本地计算 ...

  7. redis3.0 集群实战2 - 集群功能实战

    1 集群基本操作   1.1 查看当前集群状态 使用redis-trib.rb check功能查看对应的节点的状态: [root@bogon bin]# ./redis-trib.rb check 1 ...

  8. 来自亚马逊CEO Jeff Bezos的20句经验之谈

    英文原文:The 20 Smartest Things Jeff Bezos Has Ever Said 当外界对一个公司的热情有些偏离常态时, 就会出现武断的言论,亚马逊对此就深有感受.2000 年 ...

  9. playframework文档未提及,但你能做的事

    这里记录一些play!框架的文档未提及,但是可以做的一些事playframe版本1.1 1.application.conf文件可以拆分可以把application.conf文件拆成多个,需要在app ...

  10. TeamCity配置笔记

    1.编译sln 2.发布网站 3.重复代码检测 4.代码分析 5.单元测试&覆盖率测试 查看代码覆盖率 7.代码签入时自动触发编译 8.通知 1.在teamcity安装目录中找到TrayNot ...