收录日期:2019/04/20 16:50:13 时间:2016/05/31 09:33:49 标签:ASP.NET
一个朋友需要类似的效果,在网上搜索了相关资料和msdn,用了一个小时基本实现了类似的功能,在此和大家共享我的实现方法和代码。

在实现datagrid的rowspan功能,需要处理itemcreated事件,创建控件之前进行相应的操作。阅读下面代码需要熟悉DataTable、Hashtable、ItemCreated事件等。

程序中已经添加了相关注释,aspx页面没有任何数据,只包含一个DataGrid控件。下面是aspx.cs代码,仅供大家参考。

using System;
using System.Collections;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebFormEx
{
    /// <summary>
    /// Summary description for DataGridItemCreated.
    /// </summary>
    public class DataGridItemCreated : Page
    {
        protected DataGrid dgTest;
    
        private void Page_Load(object sender, EventArgs e)
        {
            // Put user code to initialize the page here
            dgTest.DataSource = GetDataSource();
            dgTest.DataBind();
        }

        #region Web Form Designer generated code
        override protected void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);
        }
        
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {    
            this.dgTest.ItemCreated += new DataGridItemEventHandler(this.dgTest_ItemCreated);
            this.Load += new EventHandler(this.Page_Load);

        }
        #endregion

        /// <summary>
        /// 缓存 rowspan 的 Hashtable
        /// </summary>
        private Hashtable rowSpans = new Hashtable();

        /// <summary>
        /// 初始化数据源,同时生成 rowspan
        /// </summary>
        /// <returns>DataTable</returns>
        private DataTable GetDataSource()
        {
            DataTable dt = new DataTable();

            // 定义结构
            dt.Columns.Add("grade", typeof(string));
            dt.Columns.Add("name", typeof(string));
            dt.Columns.Add("age", typeof(int));

            // 添加数据
            dt.Rows.Add(new object[] { "a", "A", 1 }) ;
            dt.Rows.Add(new object[] { "a", "B", 2 }) ;
            dt.Rows.Add(new object[] { "a", "C", 3 }) ;
            dt.Rows.Add(new object[] { "b", "D", 4 }) ;
            dt.Rows.Add(new object[] { "b", "E", 5 }) ;
            dt.Rows.Add(new object[] { "c", "F", 6 }) ;
            dt.Rows.Add(new object[] { "d", "G", 7 }) ;
            dt.Rows.Add(new object[] { "d", "H", 8 }) ;
            dt.Rows.Add(new object[] { "d", "I", 9 }) ;
            dt.Rows.Add(new object[] { "e", "J", 10 }) ;

            // 计算 rowspan
            InitRowSpans(dt, "grade");

            return dt;
        }

        /// <summary>
        /// 根据 DataTable 某列计算相关记录数,类似 group by - count(*) 的功能
        /// </summary>
        /// <param name="dt">DataTable</param>
        /// <param name="columnName">列名</param>
        private void InitRowSpans(DataTable dt, string columnName)
        {
            // 遍历 DataTable 的全部记录,将某列的值作为 key 存储在 Hashtable 中
            // 如果已经包含 key,在原值基础上加 1;否则默认值为 1
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                string key = dt.Rows[i][columnName].ToString().Trim();
                int count = 1;

                if (rowSpans.ContainsKey(key))
                {
                    count = (int) rowSpans[key];
                    count++;
                }

                rowSpans[key] = count;
            }
        }

        /// <summary>
        /// 返回 rowspan 数值,如果为 0,表示不包含 key
        /// </summary>
        /// <param name="key">key</param>
        /// <returns>rowspan</returns>
        private int GetRowSpan(string key)
        {
            int rowSpan = 0;
            
            if (rowSpans.ContainsKey(key))
            {
                rowSpan = (int) rowSpans[key];
                rowSpans.Remove(key);
            }

            return rowSpan;
        }

        private void dgTest_ItemCreated(object sender, DataGridItemEventArgs e)
        {
            // 参考 msdn 中 ListItemType 类型,为了简便只处理了其中两项
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                DataRowView drv = (DataRowView) e.Item.DataItem;
                string strGrade = drv["grade"].ToString().Trim();

                int rowSpan = GetRowSpan(strGrade);
                if (rowSpan <= 0)
                {
                    e.Item.Cells.RemoveAt(0);
                }
                else
                {
                    e.Item.Cells[0].RowSpan = rowSpan;
                }
            }
        }
    }
}
以下为我参考过的资料

http://blog.mvpcn.net/webdiyer/archive/2004/11/10/5350.aspx
http://dotnetjunkies.com/WebLog/jpalermo/archive/2004/07/27/20510.aspx
http://dev.csdn.net/article/31/31736.shtm


另,请大家提出更好的解决方案,指出程序的不足之处。
只想说一句:DataGrid实际上就是个htmlTable生成器,随便你怎么搞

Asp.Net下的DataGrid的多层表头 
http://blog.csdn.net/eddie005/archive/2004/11/09/173429.aspx
如果数据是统计出来,
SELECT owner, COUNT(id) AS countNum, DAY(addtime) AS newDate
FROM yzjsource
WHERE (addtime BETWEEN '2004-11-01' AND '2004-11-30')
GROUP BY DAY(addtime), owner

得到如下格式数据:

admin 14 25
admin 13 26
admin 14 27
admin 15 28
admin 13 29
ccc 2 26
ccc 1 27
ccc 1 29
etg 2 20
etg 1 23
etg 1 29
so 2 20
so 1 22

现要求转换一下显示方式 变成每用户按日期方式显示:
用户名     20 26  27  28 29(这些是日期)
admin      14 13  14  15 13
ccc            2   1      1
..............

按这种方式显示,上面的日期总共是1-30天,
如何实现
收一个。
我准备把刚才的功能完善一下,努力让程序支持类似group by 类似的功能,可以实现count/sum/avg等的简单功能
学习
学习

关于readbuffer的问题! 关于在字符模式(textmode)下的问题 如何用DELPHI编程实现对OICQ的屏蔽。(100分) 有美眉在线上吗?偶想找个美眉聊天 怎样写软件的说明啊?怎样的格式和怎样的内容? 自画TabCtrl的问题。 动态操作数据库 高分那是一定的了!外加上小弟一片诚挚的心,相信大家都知道有病的痛苦了吧?进来... Shareit! 电汇到中国银行 能不能把数组搁session里? apache上能装asp么 c/c++库函数不全啊! 分布式 PB 的问题 有任何有效的回答都会有高分送 《等待的QQ》第三章今天推出,希望大家拭目以待! 我是新手,向版主net_lover请指教!请支持!! 菜鸟求教,请各位师兄帮帮忙. 谢谢 非常痛苦的问:关于的网页设计和产品包装设计 送分 请教一个关于TOMCAT的配置文件SERVER.XML的问题。谢谢! AnsiString类的赋值问题?string1=string2 是传值还是传址??? reahat 安装软件默认位置是?可以指定安装位置吗? 好奇怪啊!这是为什么啊? Windows 2000是否支持对象缓冲(Object Pooling )? 动态操作数据库 some thoughts about immutable programming redhat7.1如何上网? Square is-a Rect? (more thoughts on immutable programming) 国内有有关 directshow 的书吗?????? NetScape Communicator是否支持VBScript客户端脚步? NetScape的浏览器到底叫NetScape Navigator还是NetScape Communicator?