GridView单元格合并

来源:互联网 发布:手机编程软件大全 编辑:程序博客网 时间:2024/06/05 14:43

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

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

 

我为GridView 创建了个RowSpan的方法 .   有一个object 参数 

为什要定义object 参数  源于ASP.NET MVC 的Routing 组件配置规则  感觉这种方式很不错..

所以使用了这种方式来进行.

 

 

复制代码
  1  public static class GridViewExtensions
  2     {
  3         /// <summary>
  4         ///  GridView行合并
  5         /// </summary>
  6         /// <param name="gridView"></param>
  7         /// <param name="field">合并参数(匿名类型)
  8         /// ColumnIndex:要合并行的索引 (以0开始,必须指定)
  9         /// ColumnControlID(可选):如果该行为模板行则必须指定 
 10         /// PropertyName:根据ID属性 默认值为Text
 11         /// Colums:(string类型)表示额外的行合并方式和ColumnIndex一样(多个使用逗号隔开,如Colums="5,6,7,8")
 12         /// 例:
 13         /// 合并第一行(第一行为模板行),绑定的一个Label名称为lblName  根据Text属性值合并  第6行方式和第一行相同
 14         /// new {ColumnIndex=0,ColumnControlID="lblName",PropertyName="Text",Columns="5"}
 15         /// </param>
 16         public static GridView RowSpan(this GridView gridView, object field)
 17         {
 18             Dictionary<stringstring> rowDictionary = ObjectLoadDictionary(field);
 19             int columnIndex = int.Parse(rowDictionary["ColumnIndex"]);
 20             string columnName = rowDictionary["ColumnControlID"];
 21             string propertyName = rowDictionary["PropertyName"];
 22             string columns = rowDictionary["Columns"];
 23             for (var i = 0; i < gridView.Rows.Count; i++)
 24             {
 25 
 26                 int rowSpanCount = 1;
 27                 for (int j = i + 1; j < gridView.Rows.Count; j++)
 28                 {
 29                     //绑定行合并处理
 30                     if (string.IsNullOrEmpty(columnName))
 31                     {
 32                         //比较2行的值是否相同
 33                         if (gridView.Rows[i].Cells[columnIndex].Text == gridView.Rows[j].Cells[columnIndex].Text)
 34                         {
 35                             //合并行的数量+1
 36                             rowSpanCount++;
 37                             //隐藏相同的行
 38                             gridView.Rows[j].Cells[columnIndex].Visible = false;
 39                             if (!string.IsNullOrEmpty(columns))
 40                             {
 41                                 columns.Split(',').ToList<string>().ForEach(c => gridView.Rows[j].Cells[int.Parse(c)].Visible=false);
 42                             }
 43                         }
 44                         else
 45                         {
 46                             break;
 47                         }
 48                     }
 49                     else
 50                     {
 51                         //模板行的合并处理
 52                         if (GetPropertyValue(gridView.Rows[i].Cells[columnIndex].FindControl(columnName), propertyName).ToString() == GetPropertyValue(gridView.Rows[j].Cells[columnIndex].FindControl(columnName), propertyName).ToString())
 53                         {
 54                             rowSpanCount++;
 55                             //隐藏相同的行
 56                             gridView.Rows[j].Cells[columnIndex].Visible = false;
 57                             if (!string.IsNullOrEmpty(columns))
 58                             {
 59                                 
 60                                 columns.Split(',').ToList<string>().ForEach(c => gridView.Rows[j].Cells[int.Parse(c)].Visible = false);
 61                             }
 62                         }
 63                         else
 64                         {
 65                             break;
 66                         }
 67                     }
 68                 }
 69                 if (rowSpanCount > 1)
 70                 {
 71                     //行合并
 72                     gridView.Rows[i].Cells[columnIndex].RowSpan = rowSpanCount;
 73                     //判断是否有额外的行需要合并
 74                     if (!string.IsNullOrEmpty(columns))
 75                     {
 76                         //额外的行合并
 77                         columns.Split(',').ToList<string>().ForEach(c => gridView.Rows[i].Cells[int.Parse(c)].RowSpan = rowSpanCount);
 78                     }
 79                     i = i + rowSpanCount - 1;
 80                 }
 81                 
 82 
 83             }
 84             return gridView;
 85         }
 86 
 87         private static Dictionary<stringstring> ObjectLoadDictionary(object fields)
 88         {
 89             Dictionary<stringstring> resultDictionary = new Dictionary<stringstring>();
 90             PropertyInfo[] property = fields.GetType().GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.GetProperty);
 91             foreach (PropertyInfo tempProperty in property)
 92             {
 93                 resultDictionary.Add(tempProperty.Name, tempProperty.GetValue(fields, null).ToString());
 94             }
 95             //指定默认值
 96             if (!resultDictionary.Keys.Contains("ColumnIndex"))
 97             {
 98                 throw new Exception("未指定要合并行的索引 ColumnIndex 属性!");
 99             }
100             if (!resultDictionary.Keys.Contains("ColumnControlID"))
101             {
102                 resultDictionary.Add("ColumnControlID"null);
103             }
104 
105             if (!resultDictionary.Keys.Contains("PropertyName"))
106             {
107                 resultDictionary.Add("PropertyName""Text");
108             }
109 
110             if (!resultDictionary.Keys.Contains("Columns"))
111             {
112                 resultDictionary.Add("Columns"null);
113             }
114             
115 
116            
117 
118             return resultDictionary;
119         }
120 
121         /// <summary>
122         ///  获取一个对象的一个属性..
123         /// </summary>
124         /// <param name="obj"></param>
125         /// <param name="PropertyName">属性名称</param>
126         /// <returns>属性的值,  如果无法获取则返回null</returns>
127         private static object GetPropertyValue(object obj, string PropertyName)
128         {
129             PropertyInfo property = obj.GetType().GetProperty(PropertyName);
130             return property.GetValue(obj,null);
131         }
132     }
复制代码

这个扩展方法的使用方式很简单

 

复制代码
 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 这种属性需要修改部分代码  也不能包含容器控件 修改部分代码可以支持容器控件

效果图

姓名性别语文数学学期张三男8690第一学期8998第二学期李四男8964第一学期7564第二学期王五男8964第一学期6393第二学期

 

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

 

复制代码
   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 });
复制代码

 

姓名性别语文数学学期张三男8690第一学期8998第二学期李四男64第一学期7564第二学期王五男8964第一学期6393第二学期

可以使用这种方式

 this.GridView1.RowSpan(new { ColumnIndex = 0, Columns = "1" }).RowSpan(new { ColumnIndex = 2 }).RowSpan(new { ColumnIndex = 3 });

 

姓名性别语文数学学期张三男8690第一学期8998第二学期李四男64第一学期75第二学期王五男89第一学期6393第二学期

 

原创粉丝点击