GridView合并表头与行的反思

      ASP.NET的GRIDVIEW确实很强大,任何一个入门的人绝对不可能忽视它。只需要指定一个数据源然后绑定,数据就呈现出来了。如果数据量不大,连分页都省了。曾几何时,我也觉得GRIDVIEW是多么的完美,于是乎网上到处学习GRIDVIEW的种种技巧。自然而然的就接触到了XX月儿的“GRIDVIEW七十二般技巧”,不得不佩服作者的研究功底还是很牛x的。但是最近遇到一个需求就是合并表头和一列中内容相同的行。由于数据呈现用的是GRIDVIEW,于是本能地在BAIDU搜索“GRIDVIEW合并表头”、“GRIDVIEW合并行”。虽然最终找到了答案,但是我却很失望。为什么这样一个功能需要在服务器端编写大量的代码?我不知道有多少人为了实现这个功能而去真正的研究了解GRIDVIEW的各种属性、方法、事件,但是我可以肯定的是如果下次作为面试题出现了,我反正仍然不会。后来思索了一段时间,觉得,这个功能用JS不是很方便很快捷吗?如果呈现数据使用REPEATER那就更加方便了,几行简单的JS代码就搞定了,为什么要搞的这么复杂?
       于是乎我开始反思,GRIDVIEW真的那么好吗?为什么它令我们变得更加愚钝?它又是如何阻碍了我们编程思维的发展?下面就关于GRIDVIEW合并行(这个答案我就不提供了,网上很多),给出我实际中的解决方案(稍微懂点Javascript就行了),依此来解释之。

      我的思路:找到表格待合并的那一列(TD元素),如果它们的内容相同,就把这些TD合并(设置其属性rowSpan)。现在的关键就是如何找到这一列。我采用给td同时设置id和name的方法(当然VS会提示你name不是td的有效属性,不过不用管它),设置相同的id是为了兼容IE,因为IE的document.getElementByName()仍然是使用id去查找元素,而FireFox则不是。

后台代码:

代码
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

public partial class MergeCell : System.Web.UI.Page
{
    
protected void Page_Load(object sender, EventArgs e)
    {
        
if (!IsPostBack)
        {
            Repeater1.DataSource 
= RetriveData();
            Repeater1.DataBind();
        }
    }

    
private DataTable RetriveData() 
    {
        var dt 
= new DataTable();
        dt.Columns.Add(
"country");
        dt.Columns.Add(
"city");
        dt.Columns.Add(
"address");
        AddRow(
"中国""武汉""武汉大学"ref dt);
        AddRow(
"中国""武汉""华中科技大学"ref dt);
        AddRow(
"美国""波士顿""哈佛大学"ref dt);
        AddRow(
"美国""波士顿""麻省理工大学"ref dt);
        AddRow(
"英国""牛津""牛津大学"ref dt);
        
return dt;
    }
    
private void AddRow(string country, string city, string address,ref DataTable dt)
    {
        var row 
= dt.NewRow();
        row[
0= country;
        row[
1= city;
        row[
2= address;
        dt.Rows.Add(row);
    }
}

前台代码:

代码
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MergeCell.aspx.cs" Inherits="MergeCell" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    
<title>无标题页</title>
    
<style type="text/css">
    BODY 
{
 background
: #e6eae9
}
TABLE 
{
    padding
:0px 0px 0px 0px;
    margin
:0px;
    width
:800px;
}
 
TH 
{
BORDER-BOTTOM
: #c1dad7 1px solid; TEXT-ALIGN: center; PADDING-BOTTOM: 6px; TEXT-TRANSFORM: uppercase; PADDING-LEFT: 12px; PADDING-RIGHT: 6px; FONT: bold 11px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; BACKGROUND: url(images/bg_header.jpg) #cae8ea no-repeat; LETTER-SPACING: 2px; COLOR: #4f6b72; BORDER-TOP: #c1dad7 1px solid; BORDER-RIGHT: #c1dad7 1px solid; PADDING-TOP: 6px
}
 
TD 
{
BORDER-BOTTOM
: #c1dad7 1px solid; PADDING-BOTTOM: 6px; PADDING-LEFT: 12px; PADDING-RIGHT: 6px; BACKGROUND: #fff; COLOR: #4f6b72; FONT-SIZE: 11px; BORDER-RIGHT: #c1dad7 1px solid; PADDING-TOP: 6px
}

    
</style>
    
<script language="javascript" type="text/javascript">
    
function mergeCell(column)
    {
    
var tds=document.getElementsByName(column);
    
for(var i=tds.length-1;i>0;i--)
    {
    
var current=tds[i];
    
var pre=tds[i-1];
    
if(current.innerHTML==pre.innerHTML)
    {pre.rowSpan
=current.rowSpan+1;current.parentNode.removeChild(current);}
    }
    }
    
</script>
</head>
<body>
    
<form id="form1" runat="server">
    
<div>
        
<asp:Repeater ID="Repeater1" runat="server">
        
<HeaderTemplate>
        
<table>
        
<tr>
        
<th>国籍</th>
        
<th>城市</th>
        
<th>地址</th>
        
</tr>
        
        
</HeaderTemplate>
        
<ItemTemplate>
        
<tr><td id="column1" name="column1"> <%#Eval("country"%></td> 
        
<td id="column2" name="column2"> <%#Eval("city"%></td> 
        
<td id="column3" name="column3"> <%#Eval("address"%></td> </tr>
        
</ItemTemplate>
        
<FooterTemplate>
        
</table>
        
</FooterTemplate>
        
</asp:Repeater>
    
</div>
    
<input id="Button1" type="button" value="开始合并行" onclick="mergeCell('column1');mergeCell('column2');" />
    
</form>
</body>
</html>

    合并前效果:

   

    

 合并后效果:

     个人觉得使用GridView最大的坏处就是阻碍了ASP.NET程序员AJAX的学习步伐,大家花费了大量时间去研究GRIDVIEW的复杂属性和复杂事件,最后得到的很可能却是效率极端低下的解决方案。ASP.NET程序员属于Web程序员的子集,HTML和JavaScript是必须要熟悉的(想想如果有天你去做JSP或者PHP),很多需求其实换一种思路更加简洁,不要把你的编程思路和精力局限在复杂的服务器控件上,使用最原始的方法往往是最通用和最易于掌握的方法。

 

 

posted @ 2010-03-06 14:32  高凡凡高  阅读(815)  评论(5编辑  收藏  举报