gridview 动态添加 数据列,绑定方法
通过继承 gridview 并且重载 createcolumns() 添加自己想要的 column,根据扩展属性中的键值对生成column。
通过继承 bouldfield,并且重载 initializedatacell() 和 getvalue() 实现自己希望的绑定方法,实现可以基于方法的数据绑定,从而可以将扩展属性中的键值绑定到对应的cell中。
gridview 是asp教程.net中表格数据显示控件中的一种,可以支持数据绑定,绑定的数据源我们一般用实现ienumerable<t>接口的对象,t可以是任何一个clr类(当然还有一些其他的数据源格式),这些大家基本都很熟悉,但是最近碰到一个新的需求:
像有一个类似于:
public class book
{
public int id { get; set; }public string name { get; set; }
public dictionary<string, object> extendproperties { get; set; }
}
其中extendproperties 是用来存储不同用户自定义的扩展属性的,用键值对的形式保存,key保存扩展属性名,value保存扩展属性值,每个用户可能的扩展属性个数和键值都不一样。
现在,如果我们需要把list<book>绑定在gridview上面,但是希望将extendproperties中的扩展属性也都显示出来,而且相应的key显示在column的header,而value则显示在相应的cell中。
起初想沿着gridview绑定一般数据的思路考虑,看是否能够通过动态属性的方式将extendproperties中的键值对匹配成相应的对象属性,(没有测试是否能够成功),但是又觉得数据绑定是控件的事情,这个不应该由数据本身来负责,那我们能否通过修改gridview本身的行为来达到这个目的呢?? 答案是肯定的!
我们都知道,gridview本身是有一个autogeneratecolumns的属性,如果设置为true的话,gridview将自动添加一些列,这些列对应book中的每一个可绑定的属性,这里是用propertydescriptor来实现的(好像是考虑到designmode,而没有用type来做反射)。根据这个思路,我们可以先看看autogeneratecolumns到底对gridview有哪些影响以及gridview本身是如何生成columns的。
通过查看gridview的源码,我们可以看到几个重要的方法:
代码
protected virtual icollection createcolumns(pageddatasource datasource, bool usedatasource);
protected virtual autogeneratedfield createautogeneratedcolumn(autogeneratedfieldproperties fieldproperties);
其中 createcolumns方法是gridview用来生成列的,而在其中会根据autogeneratecolumns属性来判断是否调用createautogeneratecolumn来自动生成相应属性的列。而且这两个方法都是可以重载的,根据我们的需求,我们可以构建一个gridview的子类,重载 createcolumns 方法,在 调用 base.createcolumns的返回结果中插入我们希望生成的column即可。
代码如下:
代码
#region properties
public bool autogenerateextendpropertiescolumn { get; set; }
public int autogeneratecolumnsafter { get; set; }
public string extendpropertiesdatafield { get; set; }
#endregion
protected override icollection createcolumns(pageddatasource datasource, bool usedatasource)
{
icollection collection = base.createcolumns(datasource, usedatasource);if (autogenerateextendpropertiescolumn )
{
arraylist list = new arraylist();icollection extendpropertiescollection = createextendpropertiescolumns(datasource, usedatasource);
arraylist list1 = new arraylist();
foreach (var c in collection)
{
list1.add(c);
}arraylist list2 = new arraylist();
if (extendpropertiescollection != null)
{
foreach (var c in extendpropertiescollection)
{
list2.add(c);
}
}int copyfrom = autogeneratecolumnsafter < list1.count ? autogeneratecolumnsafter : list1.count - 1;
copyfrom = copyfrom >= 0 ? copyfrom : -1;for (int i = 0; i <= copyfrom; i++)
{
list.add(list1[i]);
}
list.addrange(list2.toarray());for (int i = copyfrom + 1; i < list1.count; i++)
{
list.add(list1[i]);
}
return list;
}
return collection;
}protected virtual icollection createextendpropertiescolumns(pageddatasource datasource, bool usedatasource);
其中我添加了几个属性和一个新的方法:
代码
public bool autogenerateextendpropertiescolumn { get; set; }
public int autogeneratecolumnsafter { get; set; }
public string extendpropertiesdatafield { get; set; }
protected virtual icollection createextendpropertiescolumns(pageddatasource datasource, bool usedatasource);
autogenerateextendpropertiescolumn是用来判断是否要生成扩展属性对应的column,
而 autogeneratecolumnsafter是用来判断将自动生成的column应该从什么位置开始插入,
extendpropertiesdatafield 是用来指明在绑定的对象中,哪个属性是存储扩展属性的信息的,
方法 createextendpropertiescolumns是用来生成与extendproperties对应的columns.
这里只是简单的举个例子,如何通过重载 createcolumns 方法来实现自己动态添加column 的目的。
首页 1 2 末页