合并的要点:
1.datagid的单元格合并原理是table中tr,td的布局实现;
2.合并的时机实在其datagridcreate事件中实现;
3.认识一个对象TableCellCollection,它是由TableCell组成的集合,TableCell可以看成一个标题.
实现下面的效果;
前台只有一个空DataGrid,后台源码如下:
1 private DataTable dt = null; 2 protected void Page_Load(object sender, EventArgs e) 3 { 4 //数据源 5 dt = new DataTable(); 6 dt.Columns.Add("姓名"); 7 dt.Columns.Add("年龄"); 8 dt.Columns.Add("住址"); 9 dt.Columns.Add("公司"); 10 dt.Columns.Add("邮件"); 11 dt.Columns.Add("电话"); 12 13 //绑定数据源 14 mydg.DataSource = dt; 15 mydg.DataBind(); 16 17 } 18 19 protected void mydg_ItemCreated(object sender, DataGridItemEventArgs e) 20 { 21 if (e.Item.ItemType == ListItemType.Header) 22 { 23 List<CellRule> ils = new List<CellRule>(); 24 25 26 TableCellCollection tcc = e.Item.Cells; 27 tcc.Add(new TableCell()); 28 tcc[0].Text = dt.Columns[0].ColumnName; 29 tcc[0].Attributes.Add("rowspan", "2"); 30 tcc.Add(new TableCell()); 31 tcc[1].Text = dt.Columns[1].ColumnName; 32 tcc[1].Attributes.Add("rowspan", "2"); 33 tcc.Add(new TableCell()); 34 tcc[2].Attributes.Add("colspan", "4"); 35 tcc[2].Text = "详细信息</th></tr><tr>"; 36 tcc[2].HorizontalAlign = HorizontalAlign.Center; 37 38 39 tcc.Add(new TableCell()); 40 tcc[3].Text = dt.Columns[2].ColumnName; 41 tcc.Add(new TableCell()); 42 tcc[4].Text = dt.Columns[3].ColumnName; 43 tcc.Add(new TableCell()); 44 tcc[5].Text = dt.Columns[4].ColumnName; 45 tcc.Add(new TableCell()); 46 tcc[6].Text = dt.Columns[5].ColumnName; 47 48 49 50 //ils.Add(new CellRule(2, 4, "详细信息")); 51 //OganizeTcc(e.Item.Cells, ils, dt); 52 } 53 }
再将合并表头单元格封装成通用的方法:
优化后的代码如下:
1 private DataTable dt = null; 2 protected void Page_Load(object sender, EventArgs e) 3 { 4 //数据源 5 dt = new DataTable(); 6 dt.Columns.Add("姓名"); 7 dt.Columns.Add("年龄"); 8 dt.Columns.Add("住址"); 9 dt.Columns.Add("公司"); 10 dt.Columns.Add("邮件"); 11 dt.Columns.Add("电话"); 12 13 //绑定数据源 14 mydg.DataSource = dt; 15 mydg.DataBind(); 16 17 } 18 19 protected void mydg_ItemCreated(object sender, DataGridItemEventArgs e) 20 { 21 if (e.Item.ItemType == ListItemType.Header) 22 { 23 List<CellRule> ils = new List<CellRule>(); 24 25 26 //TableCellCollection tcc = e.Item.Cells; 27 //tcc.Add(new TableCell()); 28 //tcc[0].Text = dt.Columns[0].ColumnName; 29 //tcc[0].Attributes.Add("rowspan", "2"); 30 //tcc.Add(new TableCell()); 31 //tcc[1].Text = dt.Columns[1].ColumnName; 32 //tcc[1].Attributes.Add("rowspan", "2"); 33 //tcc.Add(new TableCell()); 34 //tcc[2].Attributes.Add("colspan", "4"); 35 //tcc[2].Text = "详细信息</th></tr><tr>"; 36 //tcc[2].HorizontalAlign = HorizontalAlign.Center; 37 38 39 //tcc.Add(new TableCell()); 40 //tcc[3].Text = dt.Columns[2].ColumnName; 41 //tcc.Add(new TableCell()); 42 //tcc[4].Text = dt.Columns[3].ColumnName; 43 //tcc.Add(new TableCell()); 44 //tcc[5].Text = dt.Columns[4].ColumnName; 45 //tcc.Add(new TableCell()); 46 //tcc[6].Text = dt.Columns[5].ColumnName; 47 48 49 50 ils.Add(new CellRule(2, 4, "详细信息")); 51 OganizeTcc(e.Item.Cells, ils, dt); 52 } 53 } 54 55 private void OganizeTcc(TableCellCollection tcc, List<CellRule> ils, DataTable dt) 56 { 57 tcc.Clear(); 58 ils = ils.OrderBy(p => p.iStart).ToList(); 59 List<string> secHeaders = new List<string>(); 60 //第一行 61 for (int i = 0, j = 0; j < dt.Columns.Count;) 62 { 63 if (i >= ils.Count || ils[i].iStart != j) 64 { 65 tcc.Add(new TableCell()); 66 tcc[tcc.Count - 1].Text = dt.Columns[j].ColumnName; 67 tcc[tcc.Count - 1].Attributes.Add("rowspan", "2"); 68 j++; 69 if (j == dt.Columns.Count) 70 tcc[tcc.Count - 1].Text = tcc[tcc.Count - 1].Text + "</th></tr><tr>"; 71 } 72 else 73 { 74 for (int iSec = 0; iSec < ils[i].iCount; iSec++) 75 { 76 secHeaders.Add(dt.Columns[j + iSec].ColumnName); 77 } 78 tcc.Add(new TableCell()); 79 tcc[tcc.Count-1].Text = ils[i].strHeaderText; 80 tcc[tcc.Count - 1].Attributes.Add("colspan", ils[i].iCount.ToString()); 81 tcc[tcc.Count - 1].HorizontalAlign = HorizontalAlign.Center; 82 j = j + ils[i].iCount; 83 i++; 84 if(j == dt.Columns.Count) 85 tcc[tcc.Count-1].Text = tcc[tcc.Count-1].Text+"</th></tr><tr>"; 86 } 87 88 } 89 //第二行 90 foreach (string str in secHeaders) 91 { 92 tcc.Add(new TableCell()); 93 tcc[tcc.Count - 1].Text = str; 94 } 95 }
设定合并规则的实体类:
1 public class CellRule 2 { 3 public int iStart { get; set; } 4 public int iCount { get; set; } 5 public string strHeaderText { get; set; } 6 public CellRule(int iStart, int iCount, string strHeaderText) 7 { 8 this.iStart = iStart; 9 this.iCount = iCount; 10 this.strHeaderText = strHeaderText; 11 } 12 }
现在只有一阶转二阶的方法,如果在搞成N阶通用的方法,我是暂时想不到了.就这样.