在Winfrom下的對DataGridView單元格合併

最近接了一個若差事,要在DataGridView中實現單元格合併,嘿,可搞慘我也,要是Asp.net中對我不是小菜碟嗎?找了老半天,也沒見一個現成例子,小鳥沒法只能自己寫了一個變想的,只實現了橫向單元格合併,縱向還沒時間做,如有哪位高手能把它加工,小弟會感激不盡,哈哈,費話少說,轉入正題,請看代碼:

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


怎麼樣效果行嗎?

 
發佈了10 篇原創文章 · 獲贊 11 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章