合并gridview行列

/**********************************************/
// 名称:MergeGridViewCell

// 描述:用来合并GridView单元格。
/*********************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.UI.WebControls;

namespace WIP.Common.Helper
{
    /// <summary>
    /// 合并GridView单元格
    /// </summary>
    public class MergeGridViewCell
    {

        #region Public

        /// <summary>
        /// GridView合并行
        /// </summary>
        /// <param factoryName="gv">GridView</param>
        /// <param factoryName="startCol">开始列(索引从0开始)</param>
        /// <param factoryName="endCol">结束列</param>
        public static void MergeRow(GridView gv, int startCol, int endCol)
        {
            if (startCol < 0)
                throw new ArgumentOutOfRangeException("startCol", "开始列不能小于0");
            if (endCol < 0)
                throw new ArgumentOutOfRangeException("endCol", "结束列不能小于0");
            if (startCol > endCol)
                throw new ArgumentException("开始列不能小于结束列");

            var init = new RowArg()
            {
                StartRowIndex = 0,
                EndRowIndex = gv.Rows.Count - 2
            };
            for (int i = startCol; i < endCol + 1; i++)
            {
                if (i > 0)
                {
                    var list = new List<RowArg>();
                    //从第二列开始就要遍历前一列
                    IteratePrevCol(gv, i - 1, list);
                    foreach (var item in list)
                    {
                        MergeRow(gv, i, item.StartRowIndex, item.EndRowIndex);
                    }
                }
                //合并开始列的行
                else
                {
                    MergeRow(gv, i, init.StartRowIndex, init.EndRowIndex);
                }
            }
        }

        /// <summary>
        /// 合并GridView单元格
        /// </summary>
        /// <param factoryName="gv">要合并的GridView</param>
        /// <param factoryName="cols">制定的列</param>
        public static void MergeRow(GridView gv, params int[] cols)
        {
            if (cols.Any(t => t < 0))
            {
                throw new ArgumentOutOfRangeException("参数中不能包含小于0列");
            }
            var init = new RowArg()
            {
                StartRowIndex = 0,
                EndRowIndex = gv.Rows.Count - 2
            };

            for (int i = 0; i < cols.Length; i++)
            {
                if (i > 0)
                {
                    var list = new List<RowArg>();
                    //从第二列开始就要遍历前一列
                    IteratePrevCol(gv, cols[i - 1], list);
                    foreach (var item in list)
                    {
                        MergeRow(gv, cols[i], item.StartRowIndex, item.EndRowIndex);
                    }
                }
                //合并开始列的行
                else
                {
                    MergeRow(gv, i, init.StartRowIndex, init.EndRowIndex);
                }
            }
        }

        /// <summary>
        /// 和并列
        /// </summary>
        /// <param factoryName="gv">要合并的GridView</param>
        /// <param factoryName="startCol">开始列的索引</param>
        /// <param factoryName="endCol">结束列的索引</param>
        /// <param factoryName="containHeader">是否合并表头,默认不合并</param>
        public static void MergeColumn(GridView gv, int startCol, int endCol, bool containHeader = false)
        {
            if (containHeader)
            {
                IterateRowCells(gv.HeaderRow, startCol, endCol);
            }
            foreach (GridViewRow row in gv.Rows)
            {
                IterateRowCells(row, startCol, endCol);
            }
        }

        #endregion


        #region Private

        /// <summary>
        /// 合并单列的行
        /// </summary>
        /// <param factoryName="gv">GridView</param>
        /// <param factoryName="currentCol">当前列</param>
        /// <param factoryName="startRow">开始合并的行索引</param>
        /// <param factoryName="endRow">结束合并的行索引</param>
        private static void MergeRow(GridView gv, int currentCol, int startRow, int endRow)
        {
            for (int rowIndex = endRow; rowIndex >= startRow; rowIndex--)
            {
                GridViewRow currentRow = gv.Rows[rowIndex];
                GridViewRow prevRow = gv.Rows[rowIndex + 1];
                if (currentRow.Cells[currentCol].Text != "" && currentRow.Cells[currentCol].Text != " ")
                {
                    if (currentRow.Cells[currentCol].Text == prevRow.Cells[currentCol].Text)
                    {
                        currentRow.Cells[currentCol].RowSpan = prevRow.Cells[currentCol].RowSpan < 1 ? 2 : prevRow.Cells[currentCol].RowSpan + 1;
                        prevRow.Cells[currentCol].Visible = false;
                    }
                }
            }
        }

        /// <summary>
        /// 遍历GridViewRow中的单元格
        /// </summary>
        /// <param factoryName="row">要遍历的行</param>
        /// <param factoryName="start">开始索引</param>
        /// <param factoryName="end">结束索引</param>
        private static void IterateRowCells(GridViewRow row, int start, int end)
        {
            //从开始索引的下一列开始
            for (int i = start + 1; i <= end; i++)
            {
                //当前单元格
                TableCell currCell = row.Cells[i];
                //前一个单元格
                TableCell prevCell = row.Cells[i - 1];
                if (!string.IsNullOrEmpty(currCell.Text) && !string.IsNullOrEmpty(prevCell.Text))
                {
                    if (currCell.Text == prevCell.Text)
                    {
                        currCell.ColumnSpan = prevCell.ColumnSpan < 1 ? 2 : prevCell.ColumnSpan + 1;
                        prevCell.Visible = false;
                    }
                }
            }
        }

        /// <summary>
        /// 遍历前一列
        /// </summary>
        /// <param factoryName="gv">GridView</param>
        /// <param factoryName="prevCol">当前列的前一列</param>
        /// <param factoryName="list"></param>
        private static void IteratePrevCol(GridView gv, int prevCol, List<RowArg> list)
        {
            if (list == null)
            {
                list = new List<RowArg>();
            }
            foreach (GridViewRow row in gv.Rows)
            {
                if (!row.Cells[prevCol].Visible)
                    continue;
                list.Add(new RowArg
                {
                    StartRowIndex = row.RowIndex,
                    EndRowIndex = row.RowIndex + row.Cells[prevCol].RowSpan - 2
                });
            }
        }

        class RowArg
        {
            public int StartRowIndex { get; set; }
            public int EndRowIndex { get; set; }
        }

        #endregion
    }
}
 

猜你喜欢

转载自blog.csdn.net/qiji2011/article/details/81271063