• Datagridview 实现二维表头和行合并


    借鉴别人的,改了改,没用timer

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    using System.Drawing.Design;

    namespace Salem.Library.Control.DataGridView
    {
    /// <summary>
    /// 拥有默认样式带合并表头功能的DataGridView
    /// </summary>
    public partial class DataGridViewEx : System.Windows.Forms.DataGridView
    {
    #region 字段属性

    //是否显示行号
    private bool showNum = false;
    /// <summary>
    /// 是否显示行号
    /// </summary>
    [DefaultValue(true), Description("是否显示行号")]
    public bool ShowNum
    {
    get
    {
    return showNum;
    }
    set
    {
    showNum = value;
    if (value)
    {
    this.RowHeadersVisible = true;
    }
    }
    }

    private Dictionary<int, SpanInfo> SpanRows = new Dictionary<int, SpanInfo>();

    private List<string> _mergecolumnname = new List<string>();
    /// <summary>
    /// 合并列的名称
    /// </summary>
    [MergableProperty(false), Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), Localizable(true), Description("设置或获取合并列的集合"), Browsable(true), Category("单元格合并")]
    public List<string> MergeColumnNames
    {
    get
    {
    return this._mergecolumnname;
    }
    set
    {
    this._mergecolumnname = value;
    }
    }


    #endregion

    #region 构造函数
    public DataGridViewEx()
    {
    SetProperty();
    SetStyle(
    ControlStyles.AllPaintingInWmPaint |
    ControlStyles.OptimizedDoubleBuffer |
    ControlStyles.ResizeRedraw |
    ControlStyles.DoubleBuffer, true);
    InitializeComponent();


    }
    #endregion

    #region 样式设置方法
    //设置样式属性
    private void SetProperty()
    {
    this.AutoGenerateColumns = false;
    this.BackgroundColor = Color.White;
    //设置奇数行单元格的样式
    this.AlternatingRowsDefaultCellStyle = CreatAlternatingCellStyle();
    //设置默认单元格的样式
    this.DefaultCellStyle = CreatDefaultCellStyle();
    this.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
    this.ColumnHeadersDefaultCellStyle.BackColor = Color.FromArgb(247, 247, 247);
    this.ColumnHeadersDefaultCellStyle.Font = new Font("宋体", 10);
    //this.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
    this.CellBorderStyle = DataGridViewCellBorderStyle.SunkenHorizontal;
    this.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.None;
    this.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
    this.ColumnHeadersHeight = 35;
    this.EnableHeadersVisualStyles = false;
    this.RowHeadersBorderStyle = DataGridViewHeaderBorderStyle.None;
    this.RowHeadersVisible = false;
    this.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
    this.RowTemplate.Height = 35;
    }

    //设置奇数行的样式
    private DataGridViewCellStyle CreatAlternatingCellStyle()
    {
    DataGridViewCellStyle alternatingRowStyle = new DataGridViewCellStyle();
    alternatingRowStyle.Font = new System.Drawing.Font("宋体", 10);
    //alternatingRowStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
    alternatingRowStyle.BackColor = Color.White;
    alternatingRowStyle.ForeColor = Color.Black;
    alternatingRowStyle.SelectionBackColor = Color.FromArgb(255, 230, 162);
    alternatingRowStyle.SelectionForeColor = Color.Black;
    return alternatingRowStyle;
    }

    //设置默认单元格的样式
    private DataGridViewCellStyle CreatDefaultCellStyle()
    {
    DataGridViewCellStyle defaultCellStyle = new DataGridViewCellStyle();
    //defaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
    defaultCellStyle.Font = new System.Drawing.Font("宋体", 10);
    defaultCellStyle.BackColor = Color.White;
    defaultCellStyle.ForeColor = Color.Black;
    defaultCellStyle.SelectionBackColor = Color.FromArgb(255, 230, 162);
    defaultCellStyle.SelectionForeColor = Color.Black;
    return defaultCellStyle;
    }

    /// <summary>
    /// 设置单元格和列头有边框
    /// </summary>
    public void SetGirdCellAndColHeaderBorderStyle()
    {
    this.CellBorderStyle = DataGridViewCellBorderStyle.Single;
    this.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
    }
    #endregion

    #region 重绘方法

    protected override void OnPaint(PaintEventArgs pe)
    {
    base.OnPaint(pe);
    }

    protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
    {
    try
    {
    if (e.RowIndex > -1 && e.ColumnIndex > -1)
    {
    //DrawCell(e);
    }
    else
    {
    //合并表头
    if (e.RowIndex == -1)
    {
    if (SpanRows.ContainsKey(e.ColumnIndex)) //被合并的列
    {
    //画边框
    Graphics g = e.Graphics;
    e.Paint(e.CellBounds, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);

    int left = e.CellBounds.Left, top = e.CellBounds.Top + 2,
    right = e.CellBounds.Right, bottom = e.CellBounds.Bottom;

    switch (SpanRows[e.ColumnIndex].Position)
    {
    case 1:
    left += 2;
    break;
    case 2:
    break;
    case 3:
    right -= 2;
    break;
    }

    //画底色
    g.FillRectangle(new SolidBrush(e.CellStyle.BackColor), left, top,
    right - left, (bottom - top)/2);

    //画中线
    g.DrawLine(new Pen(this.GridColor), left-2, (top + bottom) / 2,
    right, (top + bottom) / 2);

    //写合并标题
    StringFormat _sf = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };

    g.DrawString(e.Value + "", e.CellStyle.Font, Brushes.Black,
    new Rectangle(left, (top + bottom) / 2, right - left, (bottom - top) / 2), _sf);

    //写原来列标题
    StringFormat sf = new StringFormat();
    sf.Alignment = StringAlignment.Center;
    sf.LineAlignment = StringAlignment.Center;

    left = this.GetColumnDisplayRectangle(SpanRows[e.ColumnIndex].Left, true).Left - 2;
    if (left < 0) left = this.GetCellDisplayRectangle(-1, -1, true).Width;
    right = this.GetColumnDisplayRectangle(SpanRows[e.ColumnIndex].Right, true).Right - 2;
    if (right < 0) right = this.Width;
    g.DrawString(SpanRows[e.ColumnIndex].Text, this.ColumnHeadersDefaultCellStyle.Font, new SolidBrush(e.CellStyle.ForeColor),
    new Rectangle(left, top, right - left, (bottom - top)/2), sf);
    e.Handled = true;
    }
    }
    }
    base.OnCellPainting(e);
    }
    catch
    { }
    }

    //绘制行号
    protected override void OnRowPostPaint(DataGridViewRowPostPaintEventArgs e)
    {
    if (ShowNum)
    {
    this.RowHeadersVisible = true;
    SolidBrush solidBrush = new SolidBrush(Color.Black);
    e.Graphics.DrawString((e.RowIndex + 1).ToString(), e.InheritedRowStyle.Font, solidBrush, e.RowBounds.Location.X + 15, e.RowBounds.Location.Y + 5);
    }
    base.OnRowPostPaint(e);
    }

    //重绘滚动条
    protected override void OnScroll(ScrollEventArgs e)
    {
    this.ReDrawHead();
    base.OnScroll(e);
    }

    //重绘标题行
    public void ReDrawHead()
    {
    foreach (int num in this.SpanRows.Keys)
    {
    base.Invalidate(base.GetCellDisplayRectangle(num, -1, true));
    }
    }

    #endregion

    #region 自定义方法
    /// <summary>
    /// 画单元格
    /// </summary>
    /// <param name="e"></param>
    private void DrawCell(DataGridViewCellPaintingEventArgs e)
    {
    if (e.CellStyle.Alignment == DataGridViewContentAlignment.NotSet)
    {
    e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
    }
    Brush gridBrush = new SolidBrush(this.GridColor);
    SolidBrush backBrush = new SolidBrush(e.CellStyle.BackColor);
    SolidBrush fontBrush = new SolidBrush(e.CellStyle.ForeColor);
    int cellwidth;
    //上面相同的行数
    int UpRows = 0;
    //下面相同的行数
    int DownRows = 0;
    //总行数
    int count = 0;
    if (this.MergeColumnNames.Contains(this.Columns[e.ColumnIndex].Name) && e.RowIndex != -1)
    {
    cellwidth = e.CellBounds.Width;
    Pen gridLinePen = new Pen(gridBrush);
    string curValue = e.Value == null ? "" : e.Value.ToString().Trim();
    string curSelected = this.CurrentRow.Cells[e.ColumnIndex].Value == null ? "" : this.CurrentRow.Cells[e.ColumnIndex].Value.ToString().Trim();
    if (!string.IsNullOrEmpty(curValue))
    {
    #region 获取下面的行数
    for (int i = e.RowIndex; i < this.Rows.Count; i++)
    {
    if (this.Rows[i].Cells[e.ColumnIndex].Value.ToString().Equals(curValue))
    {
    //this.Rows[i].Cells[e.ColumnIndex].Selected = this.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected;
    if (!this.Rows[i].Cells[0].Value.ToString().Equals(this.Rows[e.RowIndex].Cells[0].Value.ToString()))
    break;
    DownRows++;
    if (e.RowIndex != i)
    {
    cellwidth = cellwidth < this.Rows[i].Cells[e.ColumnIndex].Size.Width ? cellwidth : this.Rows[i].Cells[e.ColumnIndex].Size.Width;
    }
    }
    else
    {
    break;
    }
    }
    #endregion
    #region 获取上面的行数
    for (int i = e.RowIndex; i >= 0; i--)
    {
    if (this.Rows[i].Cells[e.ColumnIndex].Value.ToString().Equals(curValue))
    {
    if (!this.Rows[e.RowIndex].Cells[0].Value.ToString().Equals(this.Rows[i].Cells[0].Value.ToString()))
    {
    break;
    }
    //this.Rows[i].Cells[e.ColumnIndex].Selected = this.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected;
    UpRows++;
    if (e.RowIndex != i)
    {
    cellwidth = cellwidth < this.Rows[i].Cells[e.ColumnIndex].Size.Width ? cellwidth : this.Rows[i].Cells[e.ColumnIndex].Size.Width;
    }
    }
    else
    {
    break;
    }
    }
    #endregion
    count = DownRows + UpRows - 1;
    if (count < 2)
    {
    return;
    }
    }
    if (this.Rows[e.RowIndex].Selected)
    {
    backBrush.Color = e.CellStyle.SelectionBackColor;
    fontBrush.Color = e.CellStyle.SelectionForeColor;
    }
    //以背景色填充
    e.Graphics.FillRectangle(backBrush, e.CellBounds);
    //画字符串
    PaintingFont(e, cellwidth, UpRows, DownRows, count);
    if (DownRows == 1)
    {
    e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
    count = 0;
    }
    // 画右边线
    e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1, e.CellBounds.Top, e.CellBounds.Right - 1, e.CellBounds.Bottom);

    e.Handled = true;
    }
    }
    /// <summary>
    /// 画字符串
    /// </summary>
    /// <param name="e"></param>
    /// <param name="cellwidth"></param>
    /// <param name="UpRows"></param>
    /// <param name="DownRows"></param>
    /// <param name="count"></param>
    private void PaintingFont(System.Windows.Forms.DataGridViewCellPaintingEventArgs e, int cellwidth, int UpRows, int DownRows, int count)
    {
    SolidBrush fontBrush = new SolidBrush(e.CellStyle.ForeColor);
    int fontheight = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Height;
    int fontwidth = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Width;
    int cellheight = e.CellBounds.Height;

    if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomCenter)
    {
    e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y + cellheight * DownRows - fontheight);
    }
    else if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomLeft)
    {
    e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y + cellheight * DownRows - fontheight);
    }
    else if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomRight)
    {
    e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y + cellheight * DownRows - fontheight);
    }
    else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleCenter)
    {
    e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2);
    }
    else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleLeft)
    {
    e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2);
    }
    else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleRight)
    {
    e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2);
    }
    else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopCenter)
    {
    e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1));
    }
    else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopLeft)
    {
    e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y - cellheight * (UpRows - 1));
    }
    else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopRight)
    {
    e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y - cellheight * (UpRows - 1));
    }
    else
    {
    e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2);
    }
    }


    #endregion

    #region 合并表头方法

    /// <summary>
    /// 合并列
    /// </summary>
    /// <param name="ColIndex">列的索引</param>
    /// <param name="ColCount">需要合并的列数</param>
    /// <param name="Text">合并列后的文本</param>
    public void AddSpanHeader(int ColIndex, int ColCount, string Text)
    {
    if (ColCount < 2)
    {
    //throw new Exception("行宽应大于等于2,合并1列无意义。");
    }
    //将这些列加入列表
    int Right = ColIndex + ColCount - 1; //同一大标题下的最后一列的索引
    SpanRows[ColIndex] = new SpanInfo(Text, 1, ColIndex, Right); //添加标题下的最左列
    SpanRows[Right] = new SpanInfo(Text, 3, ColIndex, Right); //添加该标题下的最右列
    for (int i = ColIndex + 1; i < Right; i++) //中间的列
    {
    SpanRows[i] = new SpanInfo(Text, 2, ColIndex, Right);
    }
    }

    /// <summary>
    /// 清除合并表头
    /// </summary>
    public void ClearSpanInfo()
    {
    this.SpanRows.Clear();
    }

    #endregion

    #region 获取绑定数据
    /// <summary>
    /// 获取显示列绑定数据
    /// </summary>
    /// <returns></returns>
    public DataTable GetVisibleBoundData()
    {
    DataTable dt = new DataTable();
    foreach (DataGridViewColumn dgvc in this.Columns)
    {
    if (!dgvc.Visible || string.IsNullOrEmpty(dgvc.HeaderText))
    {
    continue;
    }
    if (dgvc is DataGridViewTextBoxColumn || dgvc is DataGridViewComboBoxColumn || dgvc is DataGridViewLinkColumn)
    {
    if (!dt.Columns.Contains(dgvc.HeaderText) && dgvc.HeaderText.Length > 0)
    {
    if (dgvc.ValueType == null)
    {
    dt.Columns.Add(dgvc.HeaderText);
    }
    else
    {
    dt.Columns.Add(dgvc.HeaderText, dgvc.ValueType);
    }
    }
    }
    }

    foreach (DataGridViewRow dgvr in this.Rows)
    {
    if (dgvr.IsNewRow)
    {
    continue;
    }
    if (string.IsNullOrEmpty(dgvr.Cells[1].Value != null ? dgvr.Cells[1].Value.ToString() : ""))
    {
    continue;
    }
    DataRow dr = dt.NewRow();
    foreach (DataGridViewColumn dgvc in this.Columns)
    {
    if (dt.Columns.Contains(dgvc.HeaderText))
    {
    if (dgvr.Cells[dgvc.Name].FormattedValue.ToString().Length > 0)
    {
    dr[dgvc.HeaderText] = dgvr.Cells[dgvc.Name].FormattedValue;
    }
    }
    }
    dt.Rows.Add(dr);
    }

    return dt;
    }
    #endregion


    }


    [StructLayout(LayoutKind.Sequential)]
    public struct SpanInfo
    {
    /// <summary>
    /// 合并后的标题
    /// </summary>
    public string Text;
    /// <summary>
    /// 本身位置(是左边界列还是有边界列)
    /// </summary>
    public int Position;
    /// <summary>
    /// 左边界列
    /// </summary>
    public int Left;
    /// <summary>
    /// 右边界列
    /// </summary>
    public int Right;
    public SpanInfo(string Text, int Position, int Left, int Right)
    {
    this.Text = Text;
    this.Position = Position;
    this.Left = Left;
    this.Right = Right;
    }
    }
    }

    使用:

    DataTable dt = new DataTable();

         dt.Columns.Add("1");
         dt.Columns.Add("2");
         dt.Columns.Add("3");
         dt.Columns.Add("4");
         dt.Rows.Add("中国", "上海", "5000", "7000");
         dt.Rows.Add("中国", "北京", "3000", "5600");
         dt.Rows.Add("美国", "纽约", "6000", "8600");
         dt.Rows.Add("美国", "华劢顿", "8000", "9000");
         dt.Rows.Add("英国", "伦敦", "7000", "8800");
         this.rowMergeView1.DataSource = dt;
         this.rowMergeView1.ColumnHeadersHeight = 40;
         this.rowMergeView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
         //this.rowMergeView1.MergeColumnNames.Add("Column1");
         this.rowMergeView1.AddSpanHeader(2, 2, "XXXX");
  • 相关阅读:
    从键盘输入一串数据,以“exit"结束输入,且输出数据。
    判断指定盘符下文件夹是否存在
    java 输出图形
    Object对象类
    java继承
    Java封装
    java环境搭建系列:JDK环境变量详细配置
    java环境搭建系列:JDK从下载安装到简单使用
    ORACLE常见错误代码的分析与解决
    Java与C++面向对象不同点
  • 原文地址:https://www.cnblogs.com/dachuang/p/8780006.html
Copyright © 2020-2023  润新知