北天软件工作室
北天软件集网站建设、网站开发、软件开发、网站优化SEO、网站宣传、网站开发成一体的网络公司。北天软件是专业的网站建设、网站开发、设计、制作和网站国际推广、搜索引擎推广的网络公司。口号:考虑企业所需,实现企业所想。JAVA技术网热情为java爱好者服务,本网内容包括JAVA(JSP、servlet、EJB、webservice、j2ee、javabean、应用服务器、JavaScript),数据库(MYSQL、SQL Server、Sybase、Oracle、DB2、数据库综合知识),设计研究(设计模式、Struts、Spring、Hibernate、设计框架、设计综合知识),WEB2.0新技术(主要介绍AJAX),以及各种技术的入门、实例、例子等等,欢迎各位多来坐坐!◆  诚邀各位JAVA爱好者加盟!◆  本网站内容丰富,更新快,保证每周20篇以上!   旧版java技术网 | 设为首页 | 文章搜索 | RSS订阅地图
免费使用JavaCMS自助建站系统
  文章搜索:   
初学者园地  javascript  java技术  .Net技术 XML/WebService  数据库技术  web2.0技术  设计模式  设计框架  SEO技术  综合知识
您现在的位置是: 北天软件门户网>>.Net技术>>详细信息
扩展方法(2) GridView单元格合并
欢迎进入.NET社区论坛,与200万技术人员互动交流 >>进入

大家GridView都用的比较多吧..   有没遇到单元格需要合并的需求..

单元格合并原理其实很简单,就是逐行判断要合并的单元格里的值是否和上一行的相同,要是相同的话就合并,不同的话就接着判断

我们可以通过扩展方法为GridView添加单元合并

 public static class GridViewExtensions
    {
        /// <summary>
        ///  GridView行合并
        /// </summary>
        /// <param name="gridView"></param>
        /// <param name="field">合并参数(匿名类型)
        /// ColumnIndex:要合并行的索引 (以0开始,必须指定)
        /// ID(可选):如果该行为模板行则必须指定
        /// PropertyName:根据ID属性 默认值为Text
        /// Colums:(string类型)表示额外的行合并方式和ColumnIndex一样(多个使用逗号隔开,如Colums="5,6,7,8")
        /// 例:
        /// 合并第一行(第一行为模板行),绑定的一个Label名称为lblName  根据Text属性值合并  第6行方式和第一行相同
        /// new {ColumnIndex=0,ID="lblName",PropertyName="Text",Columns="5"}
        /// </param>
        public static GridView RowSpan(this GridView gridView, object field)
        {
            Dictionary<string, string> rowDictionary = ObjectLoadDictionary(field);
            int columnIndex = int.Parse(rowDictionary["ColumnIndex"]);
            string columnName = rowDictionary["ColumnName"];
            string propertyName = rowDictionary["PropertyName"];
            string columns = rowDictionary["Columns"];
            for (var i = 0; i < gridView.Rows.Count; i++)
            {

                int rowSpanCount = 1;
                for (int j = i + 1; j < gridView.Rows.Count; j++)
                {
                    //绑定行合并处理
                    if (string.IsNullOrEmpty(columnName))
                    {
                        //比较2行的值是否相同
                        if (gridView.Rows[i].Cells[columnIndex].Text == gridView.Rows[j].Cells[columnIndex].Text)
                        {
                            //合并行的数量+1
                            rowSpanCount++;
                            //隐藏相同的行
                            gridView.Rows[j].Cells[columnIndex].Visible = false;
                            if (!string.IsNullOrEmpty(columns))
                            {
                                columns.Split(',').ToList<string>().ForEach(c => gridView.Rows[j].Cells[int.Parse(c)].Visible=false);
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        //模板行的合并处理
                        if (GetPropertyValue(gridView.Rows[i].Cells[columnIndex].FindControl(columnName), propertyName) == GetPropertyValue(gridView.Rows[j].Cells[columnIndex].FindControl(columnName), propertyName))
                        {
                            rowSpanCount++;
                            //隐藏相同的行
                            gridView.Rows[j].Cells[columnIndex].Visible = false;
                            if (!string.IsNullOrEmpty(columns))
                            {
                               
                                columns.Split(',').ToList<string>().ForEach(c => gridView.Rows[j].Cells[int.Parse(c)].Visible = false);
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                if (rowSpanCount > 1)
                {
                    //行合并
                    gridView.Rows[i].Cells[columnIndex].RowSpan = rowSpanCount;
                    //判断是否有额外的行需要合并
                    if (!string.IsNullOrEmpty(columns))
                    {
                        //额外的行合并
                        columns.Split(',').ToList<string>().ForEach(c => gridView.Rows[i].Cells[int.Parse(c)].RowSpan = rowSpanCount);
                    }
                    i = i + rowSpanCount - 1;
                }
               

            }
            return gridView;
        }

        private static Dictionary<string, string> ObjectLoadDictionary(object fields)
        {
            Dictionary<string, string> resultDictionary = new Dictionary<string, string>();
            PropertyInfo[] property = fields.GetType().GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.GetProperty);
            foreach (PropertyInfo tempProperty in property)
            {
                resultDictionary.Add(tempProperty.Name, tempProperty.GetValue(fields, null).ToString());
            }
            //指定默认值
            if (!resultDictionary.Keys.Contains("ColumnIndex"))
            {
                throw new Exception("未指定要合并行的索引 ColumnIndex 属性!");
            }
            if (!resultDictionary.Keys.Contains("ColumnName"))
            {
                resultDictionary.Add("ColumnName", null);
            }

            if (!resultDictionary.Keys.Contains("PropertyName"))
            {
                resultDictionary.Add("PropertyName", "Text");
            }

            if (!resultDictionary.Keys.Contains("Columns"))
            {
                resultDictionary.Add("Columns", null);
            }
            return resultDictionary;
        }

        /// <summary>
        ///  获取一个对象的一个属性..
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="PropertyName">属性名称</param>
        /// <returns>属性的值,  如果无法获取则返回null</returns>
        private static object GetPropertyValue(object obj, string PropertyName)
        {
            PropertyInfo property = obj.GetType().GetProperty(PropertyName);

            return property.GetValue(obj,null);
        }
    }
我为GridView 创建了个RowSpan的方法 .   有一个object 参数

为什要定义object 参数  源于ASP.NET MVC 的Routing 组件配置规则  感觉这种方式很不错..所以使用了这种方式来进行.这个扩展方法的使用方式很简单

 var s = new[] {
                new { 姓名 = "张三", 性别 = "男", 语文 = 86f, 数学 = 90f, 学期 = "第一学期" }, 
                new { 姓名 = "张三", 性别 = "男", 语文 = 89f, 数学 = 98f, 学期 = "第二学期" },
                new { 姓名 = "李四", 性别 = "男", 语文 = 89f, 数学 = 64f, 学期 = "第一学期" }, 
                new { 姓名 = "李四", 性别 = "男", 语文 = 75f, 数学 = 64f, 学期 = "第二学期" },
                new { 姓名 = "王五", 性别 = "男", 语文 = 89f, 数学 = 64f, 学期 = "第一学期" }, 
                new { 姓名 = "王五", 性别 = "男", 语文 = 63f, 数学 = 93f, 学期 = "第二学期" }
            };
            this.GridView1.DataSource = s;
            this.GridView1.DataBind();
            this.GridView1.RowSpan(new { ColumnIndex = 0, Columns = "1" });
我们合并第1列的值姓名..  GirdView索引是从0开始的所以ColumnIndex=0 性别肯定和姓名对应的

可以是用Colunmns="" 这个属性来指定哪个列的合并方式和 ColumnIndex指定的列相同  多个用 ","隔开比如 Colunmns="2,3,4,5"这种方式

如果GridView中使用了模板列 则除了需要指定ColumnIndex外还需要添加ID和PropertyName属性

如 new {ColumnIndex=0,ID="lblName",PropertyName="Text",Columns="1" }

 ID 表示模板列的控件名称 PropertyName 表示值来自于控件的哪个属性. 

注:暂时只能指定普通属性如Text 或Value ;SelectedItem.Value 这种属性需要修改部分代码  也不能包含容器控件 修改部分代码可以支持容器控件

效果图

姓名 性别 语文 数学 学期
张三 男 86 90 第一学期
89 98 第二学期
李四 男 89 64 第一学期
75 64 第二学期
王五 男 89 64 第一学期
63 93 第二学期


 

合并姓名和语文相同的分数

   var s = new[] {
                new { 姓名 = "张三", 性别 = "男", 语文 = 86f, 数学 = 90f, 学期 = "第一学期" }, 
                new { 姓名 = "张三", 性别 = "男", 语文 = 89f, 数学 = 98f, 学期 = "第二学期" },
                new { 姓名 = "李四", 性别 = "男", 语文 = 89f, 数学 = 64f, 学期 = "第一学期" }, 
                new { 姓名 = "李四", 性别 = "男", 语文 = 75f, 数学 = 64f, 学期 = "第二学期" },
                new { 姓名 = "王五", 性别 = "男", 语文 = 89f, 数学 = 64f, 学期 = "第一学期" }, 
                new { 姓名 = "王五", 性别 = "男", 语文 = 63f, 数学 = 93f, 学期 = "第二学期" }
            };
            this.GridView1.DataSource = s;
            this.GridView1.DataBind();
            this.GridView1.RowSpan(new { ColumnIndex = 0, Columns = "1" });
            this.GridView1.RowSpan(new { ColumnIndex = 2 });
姓名 性别 语文 数学 学期
张三 男 86 90 第一学期
89 98 第二学期
李四 男 64 第一学期
75 64 第二学期
王五 男 89 64 第一学期
63 93 第二学期


可以使用这种方式

 this.GridView1.RowSpan(new { ColumnIndex = 0, Columns = "1" }).RowSpan(new { ColumnIndex = 2 }).RowSpan(new { ColumnIndex = 3 });
姓名 性别 语文 数学 学期
张三 男 86 90 第一学期
89 98 第二学期
李四 男 64 第一学期
75 第二学期
王五 男 89 第一学期
63 93 第二学期


还有什么额外的参数配置 大家可以提出来 我进行改进. 

 效率问题 我可以考虑使用Lambda表达式树动态

[1] [2] 下一页

关闭窗口 】   【 返回首页
推荐文章
· 浅谈.net 中的...
· C#实现的多线程异步So...
· 在 Java 平台上进行...
· 多线程Java 应用程序...
· 通过Java编程处理XML...
· 详解SQL中FOR XML子...
· 总结用XML配置的十二...
· Windows 7采用Xml格...
· 在Silverlight3中消耗...
· Eclipse SDK 3.5RC2(S...
· NetBeans 6.7 RC1发布
· JDK7中的Java NIO.2 F...
· Eclipse Ganymede:深...
· Eclipse配置的备注
· NetBeans 6.7 RC3发布
· Windows XP操作系统...
· JVM报错代码对应的错...
· 用JavaFX写用户界面...
· Java技巧:创建Excel...
· 有关Java未来的三个...
北天软件工作室 粤ICP备06079815号 版权所有©2006-2008
精彩出品 JavaCMS自助建站 (C)2006-2008 www.it3838.com limited.all rights reserved.
Powered by JavaCMS V2.6.0