GridView单元格合并 【转】

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

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

我们可以通过扩展方法为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 < string string >  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 < string string >  ObjectLoadDictionary( object  fields)
 88          {
 89              Dictionary < string string >  resultDictionary  =   new  Dictionary < string string > ();
 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第二学期

 

 

 

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

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

Lambda表达式调用的效率差别可以看

老赵的方法的直接调用,反射调用与……Lambda表达式调用这篇文章

Tag标签: 扩展方法, GridView
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值