ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C#真正意义上的用DataGridView合并表头以及表格

2022-04-25 13:34:57  阅读:242  来源: 互联网

标签:RowCount C# headerCellInfo 表头 DataGridView int new public row


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.IO;
using System.Windows.Forms;
using System.Xml.Serialization;
namespace SGTool.Controls
{
    // colum map : colum and RowPairDic
    using ColumPairDic = Dictionary<int, Dictionary<int, int>>;
    // rows map in a colum : startRow, endRow
    using RowPairDic = Dictionary<int, int>;
    public class HeaderInfo
    {
        public class HeaderCellBorderInfo
        {
            public bool Top;
            public bool Left;
            public bool Right;
            public bool Bottom;
        }
        public HeaderInfo(int rowCount, int colCount, List<HeaderCellInfo> headerCellInfoList)
        {
            RowCount = rowCount;
            ColCount = colCount;
            HeaderCellInfoList = headerCellInfoList;
            InitHeaderInfo();
        }
        private void InitHeaderInfo()
        {
            CellNames = new string[RowCount, ColCount];
            CellBorders = new HeaderCellBorderInfo[RowCount, ColCount];
            Alignments = new DataGridViewContentAlignment[RowCount, ColCount];
            CellCrosses = new Rectangle[RowCount, ColCount];
            for (int i = 0; i < RowCount; i++)
            {
                for (int j = 0; j < ColCount; j++)
                {
                    CellNames[i, j] = string.Empty;
                    CellBorders[i, j] = new HeaderCellBorderInfo();
                    Alignments[i, j] = DataGridViewContentAlignment.MiddleCenter;
                }
            }
            for (int i = 0; i < RowCount; i++)
            {
                CellBorders[i, 0].Left = true;
                CellBorders[i, ColCount - 1].Right = true;
            }
            for (int j = 0; j < ColCount; j++)
            {
                CellBorders[0, j].Top = true;
                CellBorders[RowCount - 1, j].Bottom = true;
            }
            foreach (HeaderCellInfo headerCellInfo in HeaderCellInfoList)
            {
                for (int i = headerCellInfo.Row; i < headerCellInfo.Row + headerCellInfo.RowSpan; i++)
                {
                    for (int j = headerCellInfo.Col; j < headerCellInfo.Col + headerCellInfo.ColSpan; j++)
                    {
                        CellNames[i, j] = headerCellInfo.CellName;
                        Alignments[i, j] = headerCellInfo.Alignment;
                        CellCrosses[i, j].X = headerCellInfo.Col;
                        CellCrosses[i, j].Y = headerCellInfo.Row;
                        CellCrosses[i, j].Width = headerCellInfo.ColSpan;
                        CellCrosses[i, j].Height = headerCellInfo.RowSpan;
                    }
                }
                for (int i = headerCellInfo.Row; i < headerCellInfo.Row + headerCellInfo.RowSpan; i++)
                {
                    CellBorders[i, headerCellInfo.Col + headerCellInfo.ColSpan - 1].Right = true;
                }
                for (int j = headerCellInfo.Col; j < headerCellInfo.Col + headerCellInfo.ColSpan; j++)
                {
                    CellBorders[headerCellInfo.Row + headerCellInfo.RowSpan - 1, j].Bottom = true;
                }
            }
        }
        public int RowCount;
        public int ColCount;
        public string[,] CellNames;
        public HeaderCellBorderInfo[,] CellBorders;
        public DataGridViewContentAlignment[,] Alignments;
        public Rectangle[,] CellCrosses;
        public List<HeaderCellInfo> HeaderCellInfoList;
    }
    public class HeaderCellInfo
    {
        public HeaderCellInfo()
        {
        }
        public HeaderCellInfo(int row, int col, string cellName)
        {
            Row = row;
            Col = col;
            CellName = cellName;
        }
        public HeaderCellInfo(int row, int col, int rowSpan, int colSpan, string cellName)
        {
            Row = row;
            Col = col;
            RowSpan = rowSpan;
            ColSpan = colSpan;
            CellName = cellName;
        }
        public HeaderCellInfo(int row, int col, string cellName, DataGridViewContentAlignment alignment)
        {
            Row = row;
            Col = col;
            CellName = cellName;
            Alignment = alignment;
        }
        public HeaderCellInfo(int row, int col, int rowSpan, int colSpan, string cellName, DataGridViewContentAlignment alignment)
        {
            Row = row;
            Col = col;
            RowSpan = rowSpan;
            ColSpan = colSpan;
            CellName = cellName;
            Alignment = alignment;
        }
        public int Row;
        public int Col;
        public int RowSpan = 1;
        public int ColSpan = 1;
        public string CellName = string.Empty;
        public DataGridViewContentAlignment Alignment = DataGridViewContentAlignment.MiddleCenter;
    }
    public class HeaderSetting
    {
        private int _rowCount;
        public int RowCount
        {
            get { return _rowCount; }
            set { _rowCount = value; }
        }
        private int _colCount;
        public int ColCount
        {
            get { return _colCount; }
            set { _colCount = value; }
        }
        private List<HeaderCellInfo> _headerCellInfoList = new List<HeaderCellInfo>();
        public List<HeaderCellInfo> HeaderCellInfoList
        {
            get { return _headerCellInfoList; }
            set { _headerCellInfoList = value; }
        }
    }
    public partial class DataGridViewCellMerge : DataGridView
    {
        public DataGridViewCellMerge()
        {
            InitializeComponent();
            this.RowHeadersVisible = false;
            //this.ColumnHeadersVisible = false;
            this.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
            this.AllowUserToAddRows = false;
            this.MultiSelect = false;
            this.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect;
        }
        // merged rows with same value in a colum
        private ColumPairDic columDic = new ColumPairDic();
        // header info
        private HeaderInfo _headerInfo;
        // the rule of how to merge cell
        public ColumPairDic MergedRule
        {
            set { columDic = value; }
        }
        // header info
        public HeaderInfo HeaderInfo
        {
            set
            {
                _headerInfo = value;
            }
        }
        private string _headerInfoString;
        [Editor("System.ComponentModel.Design.MultilineStringEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
        public string HeaderInfoString
        {
            get
            {
                return _headerInfoString;
            }
            set
            {
                _headerInfoString = value;
                try
                {
                    using (StringReader stringReader = new StringReader(_headerInfoString))
                    {
                        XmlSerializer xmlSerializer = new XmlSerializer(typeof(HeaderSetting));
                        HeaderSetting headerSetting = (HeaderSetting)xmlSerializer.Deserialize(stringReader);
                        if (headerSetting == null)
                        {
                            return;
                        }
                        HeaderInfo = new HeaderInfo(headerSetting.RowCount,
                            headerSetting.ColCount,
                            headerSetting.HeaderCellInfoList);
                    }
                }
                catch
                {
                }
            }
        }
        protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
        {
            try
            {
                if (e.RowIndex == -1)
                {
                    PaintHeader(e);
                }
                else
                {
                    PaintCell(e);
                }
            }
            catch
            {
            }
            base.OnCellPainting(e);
        }
        // add all the index of merged rows into a list
        private List<int> GetMergedRows(RowPairDic rowDic)
        {
            List<int> rowList = new List<int>();
            Dictionary<int, int>.KeyCollection keys = rowDic.Keys;
            foreach (int key in keys)
            {
                int startRow = -1;
                int endRow = -1;
                startRow = key;
                rowDic.TryGetValue(key, out endRow);
                for (int row = startRow; row < endRow + 1; row++)
                {
                    rowList.Add(row);
                }
            }
            return rowList;
        }
        private void PaintCell(DataGridViewCellPaintingEventArgs e)
        {
            e.CellStyle.SelectionForeColor = e.CellStyle.ForeColor;
            e.CellStyle.SelectionBackColor = e.CellStyle.BackColor;
            bool normalCell = true;
            if (columDic.ContainsKey(e.ColumnIndex))
            {
                // the colum contains some merged cells
                RowPairDic rowDic = new RowPairDic();
                columDic.TryGetValue(e.ColumnIndex, out rowDic);
                if (rowDic.Count != 0)
                {
                    // get all the merged row in a colum
                    List<int> rowList = GetMergedRows(rowDic);
                    if (rowList.Contains(e.RowIndex))
                    {
                        normalCell = false;
                        e.PaintBackground(e.ClipBounds, false);
                        // the cell is the first row of the merged cells
                        if (rowDic.ContainsKey(e.RowIndex))
                        {
                            // paint the info
                            e.PaintContent(e.ClipBounds);
                        }
                        //  the cell is a merged cell
                        if (rowDic.ContainsValue(e.RowIndex))
                        {
                            // the cell is the end row of the merged cells
                            // draw the line under the cell
                            e.Graphics.DrawLine(new Pen(this.GridColor), e.CellBounds.Left, e.CellBounds.Bottom - 1,
                                e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
                        }
                        else
                        {
                            // the cell is NOT the end row of the merged cells
                            // clear the line under the cell
                            e.Graphics.DrawLine(new Pen(e.CellStyle.BackColor), e.CellBounds.Left, e.CellBounds.Bottom - 1,
                                e.CellBounds.Right - 2, e.CellBounds.Bottom - 1);
                        }
                    }
                }// end of if (rowDic.Count != 0)
            } // end of if (columDic.ContainsKey(e.ColumnIndex))
            if (normalCell)
            {
                e.PaintBackground(e.ClipBounds, false);
                e.PaintContent(e.ClipBounds);
            }
            e.Handled = true;
        }// e
        private void PaintHeader(DataGridViewCellPaintingEventArgs e)
        {
            // head line
            if (_headerInfo == null)
            {
                return;
            }
            int[] rowTops = new int[_headerInfo.RowCount];
            int[] rowBottoms = new int[_headerInfo.RowCount];
            rowTops[0] = e.CellBounds.Top;
            for (int i = 1; i < _headerInfo.RowCount; i++)
            {
                rowTops[i] = e.CellBounds.Height * i / _headerInfo.RowCount + rowTops[0];
            }
            rowBottoms[_headerInfo.RowCount - 1] = e.CellBounds.Bottom;
            for (int i = 0; i < _headerInfo.RowCount - 1; i++)
            {
                rowBottoms[i] = rowTops[i + 1];
            }
            for (int i = 0; i < _headerInfo.RowCount; i++)
            {
                PaintHeaderCellBackground(
                    e,
                    _headerInfo.CellBorders[i, e.ColumnIndex],
                    e.CellBounds.Left,
                    rowTops[i],
                    e.CellBounds.Right,
                    rowBottoms[i]);
            }
            for (int i = 0; i < _headerInfo.RowCount; i++)
            {
                Rectangle cross = _headerInfo.CellCrosses[i, e.ColumnIndex];
                int x2 = e.CellBounds.Left;
                if (x2 < 2)
                {
                    x2++;
                }
                int w2=0;
                for (int col = cross.X; col < cross.Width + cross.X;col ++)
                {
                    w2 += this.Columns[col].Width;
                    if (col < e.ColumnIndex)
                    {
                        x2 -= this.Columns[col].Width;
                    }
                }
                //int x = this.GetCellDisplayRectangle(cross.X, -1, true).X;
                int y = rowTops[cross.Y];
                //int width = this.GetCellDisplayRectangle(cross.X + cross.Width - 1, -1, true).X +
                //    this.GetCellDisplayRectangle(cross.X + cross.Width - 1, -1, true).Width - x;
                int height = rowBottoms[cross.Y + cross.Height - 1] - y;
                PaintHeaderCellContent(
                    e,
                    _headerInfo.CellNames[i, e.ColumnIndex],
                    x2,//x,
                    y,
                    w2,//width,
                    height,
                    _headerInfo.Alignments[i, e.ColumnIndex]);
            }
            e.Handled = true;
        }
        private void PaintHeaderCellBackground(DataGridViewCellPaintingEventArgs e, HeaderInfo.HeaderCellBorderInfo border, int left, int top, int right, int bottom)
        {
            Brush brushBack = new SolidBrush(this.ColumnHeadersDefaultCellStyle.BackColor);
            e.Graphics.FillRectangle(brushBack, left, top, right - left, bottom - top);
            right--;
            bottom--;
            Pen penGrid = new Pen(this.GridColor);
            if (border.Top)
            {
                e.Graphics.DrawLine(penGrid, left, top, right, top);
            }
            if (border.Left)
            {
                e.Graphics.DrawLine(penGrid, left, top, left, bottom);
            }
            if (border.Right)
            {
                e.Graphics.DrawLine(penGrid, right, top, right, bottom);
            }
            if (border.Bottom)
            {
                e.Graphics.DrawLine(penGrid, left, bottom, right, bottom);
            }
        }
        private void PaintHeaderCellContent(DataGridViewCellPaintingEventArgs e,
            string colName,
            int x, int y, int width, int height,
            DataGridViewContentAlignment alignment)
        {
            StringFormat drawFormat = new StringFormat();
            drawFormat.Alignment = StringAlignment.Center;
            drawFormat.LineAlignment = StringAlignment.Center;
            if (alignment == DataGridViewContentAlignment.MiddleLeft)
            {
                drawFormat.Alignment = StringAlignment.Near;
            }
            e.Graphics.DrawString(colName,
                this.Font,
                new SolidBrush(e.CellStyle.ForeColor),
                new RectangleF(x, y, width, height), drawFormat);
            //e.Graphics.DrawRectangle(Pens.Red, x, y, width, height);
            //e.Graphics.DrawRectangle(Pens.Yellow, x + 1, y + 1, width - 2, height - 2);
        }
        /// <summary>
        /// Unite Cells
        /// </summary>
        /// <param name="startRow"> start row index </param>
        /// <param name="endRow"> end row index </param>
        /// <param name="endCol"> columnIndex </param>
        public void UniteCells(int startRow, int endRow, int columnIndex)
        {
            RowPairDic rowPairDic = new RowPairDic();
            if (startRow > endRow)
            {
                return;
            }
            rowPairDic.Add(startRow, endRow);
            columDic.Add(columnIndex, rowPairDic);
        }
    }// end of class 
}// end of names

 

标签:RowCount,C#,headerCellInfo,表头,DataGridView,int,new,public,row
来源: https://www.cnblogs.com/dzjl/p/16189853.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有