效果

/// <summary>
    /// DataGridView 单元格合并信息
    /// </summary>
    public struct DataGridViewMergeCellRegion
    {

public int FromRowIndex { get; set; }

public int FromColIndex { get; set; }

public int ToRowIndex { get; set; }

public int ToColIndex { get; set; }
    }

public class DataGridViewMergeColumn : DataGridViewColumn
    {

public DataGridViewMergeColumn()
            : base(new DataGridViewMergeCell())
        {

}

public DataGridViewMergeColumn(DataGridViewCell cell)
            : base(cell)
        {

}

/// <summary>
        /// 是否是进度
        /// </summary>
        public bool IsJingDu { get; set; }
    }

/// <summary>
    /// 如果列隐藏会有bug
    /// </summary>
    public class DataGridViewMergeCell : DataGridViewCell
    {

int GetMergeWidth(bool all, DataGridViewMergeCellRegion reg)
        {

int w = 0, lindex = reg.FromColIndex, lend = all ? reg.ToColIndex + 1 : this.ColumnIndex;
            int rowindex = this.RowIndex;
            DataGridViewCell cell;
            while (lindex < lend)
            {
                cell = this.DataGridView.Rows[rowindex].Cells[lindex];
                w += cell.Size.Width;
                lindex += 1;
            }
            return w;
        }
        int GetMergeHeight(bool all, DataGridViewMergeCellRegion reg)
        {

int w = 0, lindex = reg.FromRowIndex, lend = all ? reg.ToRowIndex + 1 : this.RowIndex;
            int colindex = this.ColumnIndex;
            DataGridViewCell cell;
            while (lindex < lend)
            {
                cell = this.DataGridView.Rows[lindex].Cells[colindex];
                w += cell.Size.Height;
                lindex += 1;
            }
            return w;
        }

protected override object GetFormattedValue(object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
        {
            if (value == null || value == DBNull.Value || string.IsNullOrEmpty(cellStyle.Format))
            {
                if (value == null || value == DBNull.Value)
                    return "";
                return base.GetFormattedValue(value, rowIndex, ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context);
            }
            return String.Format("{0:" + cellStyle.Format + "}", value);
        }

protected override void Paint(System.Drawing.Graphics graphics, System.Drawing.Rectangle clipBounds, System.Drawing.Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {

if (this.ColumnIndex == -1 || rowIndex == -1)
            {
                base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
                return;
            }

bool isselect = (cellState & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected;

DataGridViewMergeCellRegion? mergeinfo = this.DataGridView.GetMergeCellRegion(rowIndex, this.ColumnIndex);
            DataGridViewCell mergebegcell = null;
            //合并
            if (mergeinfo != null)
            {
                DataGridViewMergeCellRegion reg = mergeinfo.Value;

DataGridViewCell cell = this.DataGridView.Rows[reg.FromRowIndex].Cells[reg.FromColIndex];
                value = cell.Value;
                formattedValue = cell.FormattedValue;
                mergebegcell = cell;

int lrowindex = reg.FromRowIndex, lcolindex;

cellBounds.X -= GetMergeWidth(false, reg);
                cellBounds.Y -= GetMergeHeight(false, reg);
                cellBounds.Width = GetMergeWidth(true, reg);
                cellBounds.Height = GetMergeHeight(true, reg);

while (lrowindex <= reg.ToRowIndex)
                {
                    lcolindex = reg.FromColIndex;
                    while (lcolindex <= reg.ToColIndex)
                    {
                        cell = this.DataGridView.Rows[lrowindex].Cells[lcolindex];

cell.Selected = isselect;

lcolindex += 1;
                    }
                    lrowindex += 1;
                }

}

SolidBrush backBrush = new SolidBrush(isselect ? cellStyle.SelectionBackColor : cellStyle.BackColor);

Pen pen = new Pen(this.DataGridView.GridColor);

//画边框
            graphics.DrawRectangle(pen, cellBounds.X - 1, cellBounds.Y - 1, cellBounds.Width, cellBounds.Height);

Rectangle rt = new Rectangle(cellBounds.X, cellBounds.Y, cellBounds.Width - 1, cellBounds.Height - 1);
            //填充背景
            graphics.FillRectangle(backBrush, rt);

PaintData(graphics, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, isselect, mergebegcell);
            backBrush.Dispose();
            pen.Dispose();

}

/// <summary>
        /// 画数据
        /// </summary>
        protected virtual void PaintData(System.Drawing.Graphics graphics, System.Drawing.Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, bool isselect, DataGridViewCell mergebegcell)
        {
            string strvalue = null;
            if (formattedValue != null)
                strvalue = formattedValue.ToString();
            if (strvalue == null && value != null)
                strvalue = value.ToString();

if (!isselect && ((this.OwningColumn as DataGridViewMergeColumn).IsJingDu || (mergebegcell != null && (mergebegcell.OwningColumn as DataGridViewMergeColumn).IsJingDu)))
            {

decimal val;
                if (value != null && value != DBNull.Value && decimal.TryParse(value.ToString(), out val))
                {

if (formattedValue == null)
                        strvalue = val.ToString("0.00%");

if (val != 0)
                    {
                        //填充背景
                        Rectangle rt = new Rectangle(cellBounds.X + 1, cellBounds.Y + 1, (int)((cellBounds.Width - 3) * val), cellBounds.Height - 3);
                        if (rt.Width > cellBounds.Width)
                            rt.Width = cellBounds.Width - 3;
                        Color FColor = Color.FromArgb(105, 193, 137); //颜色1
                        Color TColor = Color.FromArgb(225, 244, 231);  //颜色2 
                        Brush lbackBrush = new LinearGradientBrush(rt, FColor, TColor, LinearGradientMode.Horizontal);
                        graphics.FillRectangle(lbackBrush, rt);
                        lbackBrush.Dispose();
                    }
                }
            }

if (strvalue != null && strvalue != "")
            {
                SolidBrush fontBrush = new SolidBrush(isselect ? cellStyle.SelectionForeColor : cellStyle.ForeColor);
                SizeF sizef = graphics.MeasureString(strvalue, cellStyle.Font);
                int fontheight = (int)sizef.Height;
                int fontwidth = (int)sizef.Width;

int preheight = ((cellBounds.Height - 2) - fontheight) / 2;
                int prewidth = ((cellBounds.Width - 2) - fontwidth) / 2;

float x = cellBounds.X + 1 + prewidth, y = cellBounds.Y + 1 + preheight;

graphics.DrawString(strvalue, cellStyle.Font, fontBrush, x, y);
                fontBrush.Dispose();
            }

}

}

public static class DataGridViewExtend
    {

static Dictionary<DataGridView, List<DataGridViewMergeCellRegion>> dic = new Dictionary<DataGridView, List<DataGridViewMergeCellRegion>>();

/// <summary>
        /// 添加合并
        /// </summary>
        /// <param name="dg"></param>
        /// <param name="fromrowindex">开始行Index</param>
        /// <param name="fromcolindex">开始列Index</param>
        /// <param name="torowindex">目的行Index</param>
        /// <param name="tocolindex">目的列Index</param>
        public static void AddMerge(this  DataGridView dg, int fromrowindex, int fromcolindex, int torowindex, int tocolindex)
        {

if (fromrowindex == -1 || fromcolindex == -1 || torowindex == -1 || tocolindex == -1)
            {
                return;
            }
            int lrowindex = fromrowindex, lcolindex = fromcolindex;
            if (fromrowindex > torowindex)
            {
                fromrowindex = torowindex;
                torowindex = lrowindex;
            }

if (fromcolindex > tocolindex)
            {
                fromcolindex = tocolindex;
                tocolindex = lcolindex;
            }

if (torowindex + 1 > dg.Rows.Count)
            {
                throw new Exception("目的行Index超过DataGridView行数");
            }
            if (tocolindex + 1 > dg.ColumnCount)
            {
                throw new Exception("目的列Index超过DataGridView列数");
            }

if (fromrowindex == torowindex && fromcolindex == tocolindex)
            {
                return;
            }

List<DataGridViewMergeCellRegion> list;

if (!dic.TryGetValue(dg, out list))
            {
                dg.Disposed += dg_Disposed;
                dg.DataSourceChanged += dg_DataSourceChanged;
                dg.RowHeightChanged += dg_RowHeightChanged;
                dg.ColumnWidthChanged += dg_ColumnWidthChanged;
                list = new List<DataGridViewMergeCellRegion>();
                dic.Add(dg, list);
            }

DataGridViewMergeCellRegion reg = new DataGridViewMergeCellRegion();
            reg.FromColIndex = fromcolindex;
            reg.FromRowIndex = fromrowindex;
            reg.ToColIndex = tocolindex;
            reg.ToRowIndex = torowindex;
            list.Add(reg);
        }

static void dg_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
        {
            DataGridView dg = sender as DataGridView;
            List<DataGridViewMergeCellRegion> list;
            if (dic.TryGetValue(dg, out list))
            {
                var colindex = e.Column.Index;
                foreach (DataGridViewMergeCellRegion reg in list)
                {
                    if (colindex >= reg.FromColIndex && colindex <= reg.ToColIndex)
                    {
                        int begrow = reg.FromRowIndex;
                        while (begrow <= reg.ToRowIndex)
                        {
                            int begcol = reg.FromColIndex;
                            while (begcol <= reg.ToColIndex)
                            {
                                if (begcol != colindex)
                                {
                                    dg.InvalidateCell(begcol, begrow);
                                }
                                begcol += 1;
                            }
                            begrow += 1;
                        }
                    }
                }
            }
        }

static void dg_RowHeightChanged(object sender, DataGridViewRowEventArgs e)
        {
            DataGridView dg = sender as DataGridView;
            List<DataGridViewMergeCellRegion> list;
            if (dic.TryGetValue(dg, out list))
            {
                var rowindex = e.Row.Index;
                foreach (DataGridViewMergeCellRegion reg in list)
                {
                    if (rowindex >= reg.FromRowIndex && rowindex <= reg.ToRowIndex)
                    {
                        int begrow = reg.FromRowIndex;

while (begrow <= reg.ToRowIndex)
                        {
                            if (rowindex != begrow)
                            {
                                int begcol = reg.FromColIndex;
                                while (begcol <= reg.ToColIndex)
                                {
                                    dg.InvalidateCell(begcol, begrow);
                                    begcol += 1;
                                }
                            }
                            begrow += 1;
                        }
                    }
                }

}
        }

static void dg_DataSourceChanged(object sender, EventArgs e)
        {
            dg_Disposed(sender, null);
        }

/// <summary>
        /// 获取单元格合并信息
        /// </summary>
        /// <param name="dg"></param>
        /// <param name="fromrowindex"></param>
        /// <param name="fromcolindex"></param>
        /// <returns></returns>
        public static DataGridViewMergeCellRegion? GetMergeCellRegion(this  DataGridView dg, int rowindex, int colindex)
        {
            List<DataGridViewMergeCellRegion> list;
            if (dic.TryGetValue(dg, out list))
            {
                foreach (DataGridViewMergeCellRegion reg in list)
                {
                    if (rowindex >= reg.FromRowIndex && rowindex <= reg.ToRowIndex && colindex >= reg.FromColIndex && colindex <= reg.ToColIndex)
                        return reg;
                }
            }
            return null;
        }

/// <summary>
        /// 清除合并的单元格信息
        /// </summary>
        /// <param name="dg"></param>
        public static void ClearMerge(this  DataGridView dg)
        {
            dg_Disposed(dg, null);
        }

static void dg_Disposed(object sender, EventArgs e)
        {
            DataGridView dg = sender as DataGridView;
            List<DataGridViewMergeCellRegion> list;
            if (dic.TryGetValue(dg, out list))
            {
                list.Clear();
                dic.Remove(dg);
            }
        }
    }

c# winform datagridview单元格合并相关推荐

  1. Winform Datagridview 单元格html格式化支持富文本

    Winform Datagridview 单元格html格式化支持富文本 示例: 源码:https://github.com/OceanAirdrop/DataGridViewHTMLCell 参考: ...

  2. C# DataGridView单元格合并居中

    利用CellPainting事件 方法说明:先将原始表格的单元格框线清除,再利用事件对需要显示的框线进行重新绘制,达到单元格合并的效果. int index = 0; // 用于得到合并后文字应该显示 ...

  3. C# DataGridView单元格合并与文字居中

    #region <<单元格合并配置>>public struct MergeCellsParam{public int iStartCellColumn;public int ...

  4. datagridview单元格合并居中_系统地学习Excel第17课,设置单元格格式

    上一篇:系统地学习Excel第16课,使用Excel的「替换」功能 本篇内容结构如下: 本章的知识体系 Excel工作表的整体外观由各个单元格的样式构成,单元格的样式外观在Excel的可选设置中主要包 ...

  5. C#实例:datagridview单元格合并

    这是替C#微信交流群群友做的一个小实例,目的就是在datagridview选择对应行以后,点击button后获取对应行的ip,并执行相应的操作,其实我觉得这样的话button没必要非放置到datagr ...

  6. C#的DataGridView单元格合并

    private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e){// 对第1列相 ...

  7. Winform DataGridView单元格中动态添加多个控件

    简介: 在DataGridView的单元格中动态添加多个控件.例如在DataGridViewTextBox单元格中,添加CheckBox和Button控件.主题思路就是一个动态控件的大小,位置,显示, ...

  8. cxgrid中纵横单元格合并_被合并单元格折磨疯的我,真后悔没早点知道这个Excel技巧!...

    在大家日常的工作中,经常会用到Excel合并单元格,然而合并单元格其实只是美化了表格,它会使我们后续的统计工作遇到很多麻烦,今天就给大家提供两个解决这个问题的思路. 01 合并单元格的基本操作方法 在 ...

  9. DataGridView 单元格自动填充

    在DataGridView单元格中,当输入指定字符时,自动完成填充. 通过 TextBox实现 AutoCompleteMode AutoCompleteMode.Suggest: AutoCompl ...

最新文章

  1. 基于模型的强化学习比无模型的强化学习更好?错!
  2. 人工智能,“抛弃”真实数据集?
  3. php5.6 开二级域名,PHP二级域名session共享方案
  4. 向量封包处理器(VPP)特点
  5. 华为端口聚合命令_华为交换机链路聚合命令
  6. 使用开源PhoneGap开发web app
  7. 硅钢片铁芯、坡莫合金、非晶及纳米晶软磁合金
  8. 深度学习语音降噪方法对比_一种融合骨振动传感器和麦克风信号的深度学习语音提取和降噪方法与流程...
  9. CSS学习05:文字段落排版
  10. python自然语言_Python自然语言处理 - 随笔分类 - 牛皮糖NewPtone - 博客园
  11. WEB浏览器视频流播放方案
  12. 毕业设计源码之“油价”小程序
  13. 为什么有机棉这么贵,还深受欢迎?
  14. 基于DES加密的TCP聊天程序
  15. Navicat 全部产品破解方法(MySQL/PostgreSQL等所有navicat的产品均可破解)
  16. 七、基础教程-坐标轴(Axis)
  17. AutoJs UI版
  18. java 线性回归_Java实现一元线性回归
  19. Uniapp——拨打电话、发送短信
  20. 区块链技术在证券领域的应用

热门文章

  1. SpringBoot+RabbitMq实现数据批量接收,批量操作
  2. 【UML】——构件图
  3. MEMS光开关的工作原理及应用
  4. 谷歌眼镜Mirror API开发指南之Subscriptions
  5. DOTween教程☀️DOTween的使用教程
  6. 每天学一点英文:Espresso 20210814
  7. [OpenGL]射线拾取RayPicking---(1)生成射线
  8. 【C\C++】空间中求一点到两点所构成的直线的距离
  9. jenkins中clearcase插件的使用
  10. 华为面试题----16进制转换为10进制