昨天一个同事问我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. 【C#】OOP之多态那点事

    前言: 对菜鸟开发者的忠告:花一万个小时练习 Coding,不要浪费一万小时无谓地 Debugging(也就说看代码) 看上面的UML图,我们创建一个抽象的Instrument类,类中有一个抽象方法p ...

  2. 【原创随笔】Sql2008 R2 做CQRS小结

    1.做数据同步,订阅服务器只要把数据库建好就可以了,至于表和存储过程以及其它的都不管,订阅的时候会自动创建这些信息. 2.选择事务发布(如果同步表,表至少要带主键,不然不能选择) 3.在发布的时候,用 ...

  3. jQuery: jquery.json.js

    http://api.jquery.com/jQuery.parseJSON/ http://www.json.org/json-zh.html http://fineui.codeplex.com/ ...

  4. 【poj 3080】Blue Jeans(字符串--KMP+暴力枚举+剪枝)

    题意:求n个串的字典序最小的最长公共子串. 解法:枚举第一个串的子串,与剩下的n-1个串KMP匹配,判断是否有这样的公共子串.从大长度开始枚举,找到了就break挺快的.而且KMP的作用就是匹配子串, ...

  5. es配置说明

    cluster代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的.es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来 ...

  6. Android 五大布局

    Android 五大布局:  FrameLayout(框架布局),LinearLayout (线性布局),AbsoluteLayout(绝对布局),RelativeLayout(相对布局),Table ...

  7. Snort - manual 笔记(三)

    1.6 Reading pcap files Snort 不仅可以监听interface, 还可以读取和分析已经捕获的数据包. 1.6.1 Command line arguments 下面的命令都可 ...

  8. How To Write In Sharepoint Log File 怎么对自定义的MOSS代码写日志

    How To Write In Sharepoint Log File 怎么对自定义的MOSS代码写日志 Add Microsoft.Office.Server dll in your project ...

  9. 【转】深入浅出Android Support Annotation

    [转自]http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0427/2797.html http://www.flysnow.org/201 ...

  10. 关于Fragment 不响应onActivityResult的情况分析 (

    大家都知道,可以通过使用 startActivityForResult() 和 onActivityResult() 方法来传递或接收参数. 但你是否遭遇过onActivityResult()不执行或 ...