扩展方法(2) GridView单元格合并
2009-05-21 08:30:10 来源:WEB开发网大家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表达式树动态创建Lambda表达式的效率
系列文章:
扩展方法(1) DataTable 和List 相互转换
- ››扩展Axis2框架,支持基于JVM的脚本语言
- ››扩展WebSphere Portal V6个性化功能
- ››扩展JavaScript的时候,千万要保留其原来的所有功...
- ››扩展数据:如何为 Model 750 服务器选择 I/O 扩展...
- ››扩展 JDT 实现自动代码注释与格式化
- ››扩展 secldap 的功能以验证多个数据源
- ››扩展 JUnit4 以促进测试驱动开发
- ››扩展 JUnit 测试并行程序
- ››扩展的ToolStripEx控件
- ››扩展 Eclipse 的 Java 开发工具
- ››扩展 Eclipse 辅助和规范开发流程
- ››gridview中弹窗口(根据不同的条件,弹出不同的窗...
更多精彩
赞助商链接