收录日期:2019/06/26 10:38:02 时间: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等的简单功能
学习
学习

初学jsp 用include传递参数时中文乱码 两个页面数据传递的问题 查询 在输出 怎么写 运行结果是什么?为什么? asp中gb2312 转 utf-8 (乱码问题) 请帮忙推荐 介绍 windows 消息 队列方面的书 外挂的方式取别的窗口中CVirtualGridCtrl控件的值 索引大于行数!!!各位快来帮我看看 只有一台物理主机,用VMware Workstation 组一虚拟局域网,物理主机只能是服务器么? what is the best c/c++ IDE under ubuntu? 这程序运行不了。。一运行就提示错误对话框。大家帮忙看看 哪位大侠能告诉我如何使用GCC来编译C++程序 数据库设计 a=a+1;a+=1;a++ 闭目养神的几大好处 C# 求助即时通信思路。。。 经典的25个口误,笑翻你!!! CAKEPHP 访问MS ACCESS? 救命啊!!从keyboard error到CMOS Checksum error--defaults loaded java中的facade模式 写了个抽彩程序,链接时出错,大家帮忙看看,谢谢 关于freopen的问题 excel文件批量导入access 控制台程序下UNICODE问题 散分 向一个有外键约束的表中插入数据? 向一个有外键约束的表中插入数据? 各位好,我是一名新人,希望以后多多指教。 windows XP 双硬盘启动问题 关于gridview的样式问题