[Asp.Net]GridView中根据前后列之间的关联关系合并单元格
效果如下(合并同一列中相等且连续的N个单元格,但如果前一列没有合并的话,则后一列也不合并):
![](/images/cnblogs_com/happyhippy/MergeGridView.jpg)
代码如下:
1![](/Images/OutliningIndicators/ContractedBlock.gif)
合并多列#region 合并多列
2![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
3
/// GridView合并
4
/// </summary>
5
/// <param name="gdv">GridView</param>
6
/// <param name="startColumnIndex">起始列Index</param>
7
/// <param name="endColumnIndex">结束列Index</param>
8
public static void MergeGridViewRows(GridView gdv, int startColumnIndex, int endColumnIndex)
9![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
10
if (gdv == null || endColumnIndex < startColumnIndex || gdv.Rows.Count < 2)
11
return;
12
if (startColumnIndex < 0 || endColumnIndex > gdv.Columns.Count - 1)
13
throw new ArgumentOutOfRangeException("列Index超出GridView可用列的范围。");
14
EndColumnIndex = endColumnIndex;
15
MergeCellWithSubColumn(gdv, 0, 0, gdv.Rows.Count - 1);
16
}
17
private static int EndColumnIndex = 0;
18![](/Images/OutliningIndicators/InBlock.gif)
19![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
20
/// 合并当前列和后续列
21
/// </summary>
22
/// <param name="currentColumnIndex">当前列</param>
23
/// <param name="startRowIndex">起始行</param>
24
/// <param name="endRowIndex">结束行</param>
25
/// <summary>
26
private static void MergeCellWithSubColumn(GridView gdv, int currentColumnIndex, int startRowIndex, int endRowIndex)
27![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
28
if (currentColumnIndex > EndColumnIndex)//结束递归
29
return;
30
string preValue = GetCellValue(gdv,startRowIndex, currentColumnIndex);
31
string curValue = string.Empty;
32
int endIndex = startRowIndex;
33
for (int i = startRowIndex + 1; i <= endRowIndex + 1; i++)
34![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
35
if (i == endRowIndex + 1)
36
curValue = null;//完成最后一次合并
37
else
38
curValue = GetCellValue(gdv, i, currentColumnIndex);
39
if (curValue != preValue)
40![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
41
//合并当前列
42
MergeColumnCell(gdv, currentColumnIndex, endIndex, i - 1);
43
//合并后续列
44
MergeCellWithSubColumn(gdv, currentColumnIndex + 1, endIndex, i - 1);
45
endIndex = i;
46
preValue = curValue;
47
}
48
}
49
}
50![](/Images/OutliningIndicators/InBlock.gif)
51![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
52
/// 取得GridView中单个Cell的值
53
/// </summary>
54
/// <param name="gdv">GridView</param>
55
/// <param name="rowIndex">行Index</param>
56
/// <param name="columnIndex">列Index</param>
57
/// <returns></returns>
58
private static string GetCellValue(GridView gdv, int rowIndex, int columnIndex)
59![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
60
return gdv.Rows[rowIndex].Cells[columnIndex].Text;
61
}
62![](/Images/OutliningIndicators/InBlock.gif)
63![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
64
/// 合并同列中连续的N个单元格
65
/// 注意:这里只是隐藏后续的单元格,而没有删除单元格
66
/// 主要考虑到删除后会如下两种情况:
67
/// 1. PostBack后找不回来;
68
/// 2.通过rowIndex和columnIndex来定位单元格的过程会更复杂
69
/// </summary>
70
/// <param name="gdv">GridView</param>
71
/// <param name="columnIndex">列Index</param>
72
/// <param name="startRowIndex">起始行Index</param>
73
/// <param name="endRowIndex">结束行Index</param>
74
private static void MergeColumnCell(GridView gdv, int columnIndex, int startRowIndex, int endRowIndex)
75![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
76
gdv.Rows[startRowIndex].Cells[columnIndex].RowSpan = endRowIndex - startRowIndex + 1;
77
for (int i = startRowIndex + 1; i <= endRowIndex; i++)
78
gdv.Rows[i].Cells[columnIndex].Visible = false;
79
}
![](/Images/OutliningIndicators/ContractedBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
2
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
3
![](/Images/OutliningIndicators/InBlock.gif)
4
![](/Images/OutliningIndicators/InBlock.gif)
5
![](/Images/OutliningIndicators/InBlock.gif)
6
![](/Images/OutliningIndicators/InBlock.gif)
7
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
8
![](/Images/OutliningIndicators/InBlock.gif)
9
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://www.cnblogs.com/Images/dot.gif)
10
![](/Images/OutliningIndicators/InBlock.gif)
11
![](/Images/OutliningIndicators/InBlock.gif)
12
![](/Images/OutliningIndicators/InBlock.gif)
13
![](/Images/OutliningIndicators/InBlock.gif)
14
![](/Images/OutliningIndicators/InBlock.gif)
15
![](/Images/OutliningIndicators/InBlock.gif)
16
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
17
![](/Images/OutliningIndicators/InBlock.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
20
![](/Images/OutliningIndicators/InBlock.gif)
21
![](/Images/OutliningIndicators/InBlock.gif)
22
![](/Images/OutliningIndicators/InBlock.gif)
23
![](/Images/OutliningIndicators/InBlock.gif)
24
![](/Images/OutliningIndicators/InBlock.gif)
25
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
26
![](/Images/OutliningIndicators/InBlock.gif)
27
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://www.cnblogs.com/Images/dot.gif)
28
![](/Images/OutliningIndicators/InBlock.gif)
29
![](/Images/OutliningIndicators/InBlock.gif)
30
![](/Images/OutliningIndicators/InBlock.gif)
31
![](/Images/OutliningIndicators/InBlock.gif)
32
![](/Images/OutliningIndicators/InBlock.gif)
33
![](/Images/OutliningIndicators/InBlock.gif)
34
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://www.cnblogs.com/Images/dot.gif)
35
![](/Images/OutliningIndicators/InBlock.gif)
36
![](/Images/OutliningIndicators/InBlock.gif)
37
![](/Images/OutliningIndicators/InBlock.gif)
38
![](/Images/OutliningIndicators/InBlock.gif)
39
![](/Images/OutliningIndicators/InBlock.gif)
40
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://www.cnblogs.com/Images/dot.gif)
41
![](/Images/OutliningIndicators/InBlock.gif)
42
![](/Images/OutliningIndicators/InBlock.gif)
43
![](/Images/OutliningIndicators/InBlock.gif)
44
![](/Images/OutliningIndicators/InBlock.gif)
45
![](/Images/OutliningIndicators/InBlock.gif)
46
![](/Images/OutliningIndicators/InBlock.gif)
47
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
48
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
49
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
50
![](/Images/OutliningIndicators/InBlock.gif)
51
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
52
![](/Images/OutliningIndicators/InBlock.gif)
53
![](/Images/OutliningIndicators/InBlock.gif)
54
![](/Images/OutliningIndicators/InBlock.gif)
55
![](/Images/OutliningIndicators/InBlock.gif)
56
![](/Images/OutliningIndicators/InBlock.gif)
57
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
58
![](/Images/OutliningIndicators/InBlock.gif)
59
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://www.cnblogs.com/Images/dot.gif)
60
![](/Images/OutliningIndicators/InBlock.gif)
61
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
62
![](/Images/OutliningIndicators/InBlock.gif)
63
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
64
![](/Images/OutliningIndicators/InBlock.gif)
65
![](/Images/OutliningIndicators/InBlock.gif)
66
![](/Images/OutliningIndicators/InBlock.gif)
67
![](/Images/OutliningIndicators/InBlock.gif)
68
![](/Images/OutliningIndicators/InBlock.gif)
69
![](/Images/OutliningIndicators/InBlock.gif)
70
![](/Images/OutliningIndicators/InBlock.gif)
71
![](/Images/OutliningIndicators/InBlock.gif)
72
![](/Images/OutliningIndicators/InBlock.gif)
73
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
74
![](/Images/OutliningIndicators/InBlock.gif)
75
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://www.cnblogs.com/Images/dot.gif)
76
![](/Images/OutliningIndicators/InBlock.gif)
77
![](/Images/OutliningIndicators/InBlock.gif)
78
![](/Images/OutliningIndicators/InBlock.gif)
79
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
使用:
GridView的PreRender事件中调用:MergeGridViewRows(gridView,0,5)
也可以将上面的代码改成JS版本,在客户端执行。