摘自:http://www.cnblogs.com/ASPnet_yuan/archive/2010/12/22/Table.html
【摘要】: 在信息查询、统计等方面, 表中的单元格相同部分适当合并, 会使表中数据非常直观。本文讨论了ASP.NET环境下, 使用C# 实现单元格动态合并技术, 该方案对其它应用也有重要意义。
【关键词】: ASP.NET, 合并单元格, Table,Web 控件
一、引言
Table 控件可以用给定的静态内容在设计时生成表, 但Table 控件的威力通常在用动态内容以编程方式生成表时才会体现出来。Table 控件允许生成HTML 表并以直接方式指定其属性。Table 类主要由控件开发人员使用。
所有的Web 控件都有两个基本属性, 第一个属性是runat ="server", 它告诉ASP.NET 在服务器上处理控件, 并为控件执行所有的ASP.NET 功能, 包括状态的创建。第二个属性是ID, 指明该控件的唯一标识代号, 以便在代码中操纵该控件。
Table 控件主要由3 个组件组成:Table、TableRow和TableCell。
二、动态创建表
动态地创建一个表一般包含三个步骤:
( 1) 在.aspx 文件中, 在<body></body>里用一个asp 标签创建Table1 控件, Table1 就是一个对象。
<body>
<form id="Form1" method="post" runat="server">
<asp:Table id="Table1" runat="server"> </asp:Table>
</body>
Table 的具体生成可在<script></script>中通过函数写在.aspx文件中完成, 也可直接写在.cs 文件中。在具体生成上根据如下过程的:
( 2) 创建表格行对象TableRow(), 并向表中添加该行, 根据需要设置表格行的相关属性。
( 3) 创建表格单元格对象TableCell(), 并向表行中添加该单元格, 根据需要设置单元格的相关属性。
( 4) 对表中的各行重复(2)(3)过程。
实现方法的核心代码如下:
private void DrawTable (ref Table table, ref int seed)
{
TableRow r ; // 表格行对象
TableCell c ; // 表格单元格对象
for(int k=0; k<10; k++) // 行数控制
{
int s = 0; // 列标识变量
r = new TableRow(); table.Rows.Add(r); // 创建行
// 第0 列
c = new TableCell(); r.Cells.Add(c); // 创建列
c.ID = ProduceID(ref seed, s++);
c.Text = k.ToString(); // 第0 列内容
// 第1 列
c = new TableCell(); r.Cells.Add(c); // 创建列
c.ID = ProduceID(ref seed, s++);
c.Text = k.ToString(); // 第1 列内容
}
}
上述创建的是一个表格的表体的结构, 其内容根据具体需要可从数据库中获得。
三、表格标题行的创建与单元格合并
实际上, 表格标题行是按行构成的。如下面的示例表格中"院系"、"专业"、"班级"、"招生"和"备注"是第0 行, 而"人数"和"女生"是第1 行。其中"院系"、"业"、"班级"和"备注"占2 行, "招生"占2 列。
单元格合并主要用到单元格的RowSpan 和ColumnSpan 两个属性。实现示例表格标题行的核心代码如下:
private void SetTableHead(Table table, ref int seed)
{ // 第0 行
TableRow r = new TableRow(); table.Rows.Add(r);
TableHeaderCell h; // 标题行单元格对象
string[] sa1 = {"院系", "专业", "班级"};
for (int col = 0; col < 3; col++)
{
h = new TableHeaderCell(); r.Cells.Add(h); // 创建列
h.RowSpan = 2; // 占2 行
h.ID = ProduceID(ref seed, col);
h.Text = sa1[col];
}
h = new TableHeaderCell(); row1.Cells.Add(h);
h.ColumnSpan = 2; // 占2 列
h.Text = "招生";
h = new TableHeaderCell(); row1.Cells.Add(h);
h.RowSpan = 2; // 占2 行
h.Text = "备注";
// 第1 行
r = new TableRow(); table.Rows.Add(r); // 创建行
h = new TableHeaderCell(); r.Cells.Add(h); // 创建列
h.Text = "人数";
h = new TableHeaderCell(); r.Cells.Add(h);
h.Text = "女生";
}
四、表体单元格合并
由于表体中数据具有动态性的特点, 其纵向合并方法, 一般是逐行判断要合并的单元格里的值是否和上一行同列的相同,要是相同的话就合并, 不同的话就接着判断。
该方法的核心代码如下:
private void ColMerge(ref Table table, int col, int startRow)
{
int rowsCount = table.Rows.Count;
if (startRow >= rowsCount) return; // 超界返回
int rSpan = 0; //单元格跨越的行数
int s = startRow; //起始行
string text1 = table.Rows[startRow].Cells[col].Text;
for (int r = startRow; r < rowsCount; r++)
{
string text2 = GetCellByID(table.Rows[r], col).Text;
if (text1.Equals(text2))
{
rSpan++;
TableCell cell1 = GetCellByID(table.Rows[r], col);
if(r! =s) table.Rows[r].Cells.Remove(cell1); //移除
}
else
{
GetCellByID(table.Rows[s], col).RowSpan=rSpan;
rSpan = 0;
s = r- - ;
text1 = text2;
}
}
GetCellByID(table.Rows[s], col).RowSpan=rSpan;
}
五、调用
private int m_Seed = 0; //
private void Page_Load(object sender, System.EventArgs e)
{
this.SetTableHead(Table1, ref m_Seed); // 标题行
this.DrawTable(ref Table1, ref m_Seed); // 表体
ColMerge(ref table, 0, 1); //从第1 行起合并第0 列
}