ASP.net下實現合并單元格相對簡單,很大程度上是因為基於HTML;Winform下的DataGridView實現比較繁瑣,目前看似只有重繪這條路;如果嫌累可以使用Developer Express .NET的全套解決方案;

[轉載]二维表头的实现,來源不明

int top = 0;
        int left = 0;
        int height = 0;
        int width1 = 0;
        private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            #region 重绘datagridview表头
            DataGridView dgv = (DataGridView)(sender);
            if (e.RowIndex == -1 && (e.ColumnIndex == 3 || e.ColumnIndex == 4))
            {

//e.CellStyle.Font = new Font(dataGridView1.DefaultCellStyle.Font, FontStyle.Bold);
                //e.CellStyle.WrapMode = DataGridViewTriState.True;
                if (e.ColumnIndex == 3)
                {
                    top = e.CellBounds.Top;
                    left = e.CellBounds.Left;
                    height = e.CellBounds.Height;
                    width1 = e.CellBounds.Width;
                }

int width2 = this.dataGridView1.Columns[4].Width;

Rectangle rect = new Rectangle(left, top, width1 + width2, e.CellBounds.Height);
                using (Brush backColorBrush = new SolidBrush(e.CellStyle.BackColor))
                {
                    //抹去原来的cell背景
                    e.Graphics.FillRectangle(backColorBrush, rect);
                }

using (Pen gridLinePen = new Pen(dgv.GridColor))
                {
                    e.Graphics.DrawLine(gridLinePen, left, top, left + width1 + width2, top);
                    e.Graphics.DrawLine(gridLinePen, left, top + height / 2, left + width1 + width2, top + height /

2);
                    e.Graphics.DrawLine(gridLinePen, left + width1, top + height / 2, left + width1, top + height);

//计算绘制字符串的位置
                    string columnValue = "Year";
                    SizeF sf = e.Graphics.MeasureString(columnValue, e.CellStyle.Font);
                    float lstr = (width1 + width2 - sf.Width) / 2;
                    float rstr = (height / 2 - sf.Height) / 2;
                    //画出文本框

if (columnValue != "")
                    {
                        e.Graphics.DrawString(columnValue, e.CellStyle.Font,
                                                   new SolidBrush(e.CellStyle.ForeColor),
                                                     left + lstr,
                                                     top + rstr,
                                                     StringFormat.GenericDefault);
                    }

//计算绘制字符串的位置
                    columnValue = "局网台资产额";
                    sf = e.Graphics.MeasureString(columnValue, e.CellStyle.Font);
                    lstr = (width1 - sf.Width) / 2;
                    rstr = (height / 2 - sf.Height) / 2;
                    //画出文本框

if (columnValue != "")
                    {
                        e.Graphics.DrawString(columnValue, e.CellStyle.Font,
                                                   new SolidBrush(e.CellStyle.ForeColor),
                                                     left + lstr,
                                                     top + height / 2 + rstr,
                                                     StringFormat.GenericDefault);
                    }

//计算绘制字符串的位置
                    columnValue = "网络资产额";
                    sf = e.Graphics.MeasureString(columnValue, e.CellStyle.Font);
                    lstr = (width2 - sf.Width) / 2;
                    rstr = (height / 2 - sf.Height) / 2;
                    //画出文本框

if (columnValue != "")
                    {
                        e.Graphics.DrawString(columnValue, e.CellStyle.Font,
                                                   new SolidBrush(e.CellStyle.ForeColor),
                                                     left + width1 + lstr,
                                                     top + height / 2 + rstr,
                                                     StringFormat.GenericDefault);
                    }

}
                e.Handled = true;

}
            #endregion
        }

http://www.cnblogs.com/liuke209/archive/2006/07/29/463023.html

using System;
using System.Collections.Generic;
using System.Text;

using System.Windows.Forms;
using System.Collections;
using System.Drawing;

namespace OPSS.Logic.Checks
{
    /// <summary>
    /// 对DataGridView进行合并操作的类
    /// </summary>
    public class DGVOper
    {
                
        private static SortedList rowSpan = new SortedList();//取得需要重新绘制的单元格
        private static string rowValue = "";//重新绘制的文本框内容
       
        #region  单元格绘制
        /// <summary>
        ///
        /// DataGridView合并单元格(横向)
        /// </summary>
        /// <param name="dgv">绘制的DataGridview </param>
        /// <param name="cellArgs">绘制单元格的参数(DataGridview的CellPainting事件中参数)</param>
        /// <param name="minColIndex">起始单元格在DataGridView中的索引号</param>
        /// <param name="maxColIndex">结束单元格在DataGridView中的索引号</param>
        public static void MerageRowSpan(DataGridView dgv, DataGridViewCellPaintingEventArgs cellArgs, int minColIndex, int maxColIndex)
        {
            if (cellArgs.ColumnIndex < minColIndex || cellArgs.ColumnIndex > maxColIndex) return;

Rectangle rect=new Rectangle();
            using (Brush gridBrush = new SolidBrush(dgv.GridColor),
                backColorBrush = new SolidBrush(cellArgs.CellStyle.BackColor))
            {
                //抹去原来的cell背景
                cellArgs.Graphics.FillRectangle(backColorBrush, cellArgs.CellBounds);
            }
            cellArgs.Handled = true;

if (rowSpan[cellArgs.ColumnIndex] == null)
            {
                //首先判断当前单元格是不是需要重绘的单元格
                //保留此单元格的信息,并抹去此单元格的背景
                rect.X = cellArgs.CellBounds.X;
                rect.Y = cellArgs.CellBounds.Y;
                rect.Width = cellArgs.CellBounds.Width;
                rect.Height = cellArgs.CellBounds.Height;
               
                rowValue += cellArgs.Value.ToString();
                rowSpan.Add(cellArgs.ColumnIndex, rect);
                if (cellArgs.ColumnIndex != maxColIndex)
                    return;
                MeragePrint(dgv, cellArgs, minColIndex, maxColIndex);
            }
            else
            {
                IsPostMerage(dgv, cellArgs, minColIndex, maxColIndex);
            }
        }

/// <summary>
        /// 不是初次单元格绘制
        /// </summary>
        /// <param name="dgv"></param>
        /// <param name="cellArgs"></param>
        /// <param name="minColIndex"></param>
        /// <param name="maxColIndex"></param>
        public static void IsPostMerage(DataGridView dgv, DataGridViewCellPaintingEventArgs cellArgs, int minColIndex, int maxColIndex)
        {
            //比较单元是否有变化
            Rectangle rectArgs = (Rectangle)rowSpan[cellArgs.ColumnIndex];
            if (rectArgs.X != cellArgs.CellBounds.X || rectArgs.Y != cellArgs.CellBounds.Y
                || rectArgs.Width != cellArgs.CellBounds.Width || rectArgs.Height != cellArgs.CellBounds.Height)
            {
                rectArgs.X = cellArgs.CellBounds.X;
                rectArgs.Y = cellArgs.CellBounds.Y;
                rectArgs.Width = cellArgs.CellBounds.Width;
                rectArgs.Height = cellArgs.CellBounds.Height;
                rowSpan[cellArgs.ColumnIndex] = rectArgs;
            }
            MeragePrint(dgv,cellArgs,minColIndex,maxColIndex);
           
        }

//画制单元格
        private static void MeragePrint(DataGridView dgv, DataGridViewCellPaintingEventArgs cellArgs, int minColIndex, int maxColIndex)
            {

int width = 0;//合并后单元格总宽度
                int height = cellArgs.CellBounds.Height;//合并后单元格总高度
               
                for (int i = minColIndex; i <= maxColIndex;i++ )
                {
                    width += ((Rectangle)rowSpan[i]).Width;
                }

Rectangle rectBegin = (Rectangle)rowSpan[minColIndex];//合并第一个单元格的位置信息
                Rectangle rectEnd = (Rectangle)rowSpan[maxColIndex];//合并最后一个单元格的位置信息
               
                //合并单元格的位置信息
                Rectangle reBounds = new Rectangle();
                reBounds.X = rectBegin.X;
                reBounds.Y = rectBegin.Y;
                reBounds.Width = width - 1;
                reBounds.Height = height - 1;

using (Brush gridBrush = new SolidBrush(dgv.GridColor),
                             backColorBrush = new SolidBrush(cellArgs.CellStyle.BackColor))
                {
                    using (Pen gridLinePen = new Pen(gridBrush))
                    {
                        // 画出上下两条边线,左右边线无
                        Point blPoint = new Point(rectBegin.Left, rectBegin.Bottom - 1);//底线左边位置
                        Point brPoint = new Point(rectEnd.Right - 1, rectEnd.Bottom - 1);//底线右边位置
                        cellArgs.Graphics.DrawLine(gridLinePen, blPoint, brPoint);//下边线

Point tlPoint = new Point(rectBegin.Left, rectBegin.Top);//上边线左边位置
                        Point trPoint = new Point(rectEnd.Right - 1, rectEnd.Top);//上边线右边位置
                        cellArgs.Graphics.DrawLine(gridLinePen, tlPoint, trPoint); //上边线

Point ltPoint = new Point(rectBegin.Left, rectBegin.Top);//左边线顶部位置
                        Point lbPoint = new Point(rectBegin.Left, rectBegin.Bottom - 1);//左边线底部位置
                        cellArgs.Graphics.DrawLine(gridLinePen, ltPoint, lbPoint); //左边线

Point rtPoint = new Point(rectEnd.Right - 1, rectEnd.Top);//右边线顶部位置
                        Point rbPoint = new Point(rectEnd.Right - 1, rectEnd.Bottom - 1);//右边线底部位置
                        cellArgs.Graphics.DrawLine(gridLinePen, rtPoint, rbPoint); //右边线

//计算绘制字符串的位置
                        SizeF sf = cellArgs.Graphics.MeasureString(rowValue, cellArgs.CellStyle.Font);
                        float lstr = (width - sf.Width) / 2;
                        float rstr = (height - sf.Height) / 2;

//画出文本框
                        if (rowValue != "")
                        {
                            cellArgs.Graphics.DrawString(rowValue, cellArgs.CellStyle.Font,
                                                       new SolidBrush(cellArgs.CellStyle.ForeColor),
                                                         rectBegin.Left + lstr,
                                                         rectBegin.Top + rstr,
                                                         StringFormat.GenericDefault);
                        }
                    }
                    cellArgs.Handled = true;
                }
                   
            }
        #endregion
    
    }
}

=======================================================
在DataGridView页面的DataGridView的CellPainting事件中写下下面代码就OK了

#region 统计行单元格绘制
        private void dgConfirm_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.RowIndex!=-1  && dgConfirm.Rows[e.RowIndex].Cells[1].Value.ToString()==" "  )
            {
                e.CellStyle.Font = new Font(dgConfirm.DefaultCellStyle.Font, FontStyle.Bold);
                e.CellStyle.WrapMode = DataGridViewTriState.True;
                DGVOper.MerageRowSpan(dgConfirm, e, 1, 2);
            }
           
            //重绘统计行的选择框背景
            if ((e.RowIndex == dgConfirm.Rows.Count - 1) && (e.ColumnIndex==0))
            {
                Rectangle rect = new Rectangle();
                rect.X = e.CellBounds.X;
                rect.Y = e.CellBounds.Y;
                rect.Width = e.CellBounds.Width;
                rect.Height = e.CellBounds.Height;
                e.Paint(rect,DataGridViewPaintParts.ContentBackground);
                e.PaintBackground(rect,false);
                e.Handled = true;
          }
        }
        #endregion


怎么样效果行吗?但是沒有時間垂直合并的

DataGridView合并表头实现 、二维表头的实现相关推荐

  1. C# 生成带二维表头的Excel表

    这里用到第三方库Microsoft.Office.Interop.Excel,添加该引用后,鼠标右键该引用查看属性,将嵌入互操作类型true改为fase,电脑上需要下载office2013或者更高版本 ...

  2. php 二维数组根据键值合并二维数组_php数组实现根据某个键值将相同键值合并生成新二维数组的方法详解...

    这篇文章主要介绍了php数组实现根据某个键值将相同键值合并生成新二维数组的方法,涉及php数组的遍历.赋值相关运算技巧,需要的朋友可以参考下 本文实例讲述了php数组实现根据某个键值将相同键值合并生成 ...

  3. php 判断键值重复合并,php数组实现根据某个键值将相同键值合并生成新二维数组的方法...

    本文实例讲述了php数组实现根据某个键值将相同键值合并生成新二维数组的方法.分享给大家供大家参考,具体如下: 源数据: $infos = array( array( a => 36, b =&g ...

  4. php 二维数组字段合并,PHP将二维数组某一个字段相同的数组合并起来的方法,二维数组数组_PHP教程...

    PHP将二维数组某一个字段相同的数组合并起来的方法,二维数组数组 本文实例讲述了PHP将二维数组某一个字段相同的数组合并起来的方法.分享给大家供大家参考,具体如下: 例子: array(3) { [0 ...

  5. 两个listmap合并去重_Excel 二维表,相同行标题的多个值各占一行,如何合并为一行?...

    员工考勤表,本不复杂,如果用一维表输入原始数据,需要提交给领导看的时候再转换成容易识别的二维表,这是最推荐的做法. 如果要直接做二维表,也可以,但是就要做成标准的二维表,比如,每天的员工姓名都应该是唯 ...

  6. 无广告托管应用,免费的应用分发平台,提供下载次数等数据统计,Android、ios应用合并,一个二维码搞定

    前言 省去自建服务器的麻烦,并且提供了下载次数等数据统计,可以随时查看历史版本,一个二维码搞定Android和ios,扫码时可根据机型自动识别,给开发者提供很大便利,不仅免费而且操作非常的简单. 1. ...

  7. PHP 数组合并,将二维或多维数组合并为 一维数组

    1.二维合并为一维数组 mixed array_reduce ( array array,callablearray,callablearray , callable callback [, mixe ...

  8. 苹果安卓APP下载地址合并为一个二维码

    公司做APP推广,因为苹果系统和安卓系统的区别,上架的应用市场也不同,导致了苹果和安卓各有一个APP下载二维码,这样推广起来很不方便,所以一直想实现能够一个二维码同时兼具苹果和安卓下载地址.苹果用户扫 ...

  9. 微信支付宝合并为一个二维码支付的实现

    背景说明 我们是一个位于三线城市的购物中心,虽然已经开业多年,但是受益于良好的招商和日常运营,客流量在同城同类型项目中一直比较稳定.在节假日出场车流高峰期的时候,由于人工收费的效率问题,会导致车辆积压 ...

最新文章

  1. mysql用户角色权限代码_用户权限管理代码
  2. 【浏览器】缩放是缩放CSS像素(缩放比例为1时,一个CSS像素等于一个屏幕像素)
  3. 用批处理实现文本文件中指定字符串的替换 zz
  4. 测试Join(插队)
  5. Chrome浏览器嗅探功能技巧
  6. rapidxml 文件读写,增加删除节点
  7. 维基百科的语料库下载以及后续操作(一)2020年6月【包括opencc下载避雷,繁转简】
  8. 计算机考试电子邮件怎么回复,计算机基础知识电子邮件使用技巧集锦(二)
  9. 风螺旋公切线算法详解
  10. 苹果蕉文案:水果店苹果蕉推广文案
  11. js下载Word文档
  12. eplan php文件夹,EPLAN P8 导入部件库的方法-mdb文件
  13. 纳米结构中的磁斯格明子
  14. 猫眼即将上映的电影数据
  15. 软件安全实验(一)PEVIEW-弹窗操作
  16. 信息组织 | 信息组织的基本原理
  17. 陕西省最优秀的几所高中-五大名校,西北工业大学附属中学蝉联第一
  18. Windows 10 如何使用iso安装.Net Framework 3.5
  19. UI设计师必备的13款常用设计工具
  20. 如何利用迅雷下载百度云

热门文章

  1. python Pool常用函数用法总结
  2. python神经网络风格_[Deep-Learning-with-Python]使用LSTM生成尼采风格文章
  3. Linux中Sleep和Wait命令的使用方式
  4. C++ 枚举类型介绍
  5. mysql 硬解析 软解析_ORACLE sql语句的硬解析与软解析(收藏)
  6. Flask中的重定向redirect和url_for
  7. 第1关:实现一个顺序存储的线性表
  8. weex css单位,weex 踩坑
  9. p6安装后怎么连接oracle的数据库,p6-oraclexe数据库连接不上处理方法内部版20151012.doc...
  10. I - Watering Flowers CodeForces - 617C