用SPGridView显示SharePoint内容
我们在SharePoint上查看列表视图的时候,默认的那个Web部件(ListViewWebPart)提供了丰富且友好的功能,可以在上面进行排序、筛选等操作,每个列表条目上还有一个友好的下拉菜单。在2007中,SharePoint内置了一个类似的控件SPGridView来达到类似的效果,所以当我们需要显示一些其他数据的时候(例如来自SQL Server等),将数据绑定到SPGridView上就可以实现类似的排序和筛选效果,而不用写一行排序筛选相关的代码,下拉菜单的实现通过几行简单代码可以搞定。
关于SPGridView网上有很多文章介绍它的用法(例如jianyi的这篇文章,其中介绍了如何通过ObjectDataSource来显示一个SharePoint风格的数据视图,并有一个比较简单的下拉菜单,也可以做排序和筛选)。但是文章的后半部分,也就是如何显示SharePoint列表数据的部分,有比较大的问题,而且根据我搜索的结果,也很少有文章提到这个问题。
网上的一些例子在使用SharePoint列表作为数据源的时候,直接使用了SPDataSource来进行数据绑定。这个东西也是2007中新加上去的,配合SPGridView的一个控件,可以直接通过List属性绑定到一个SharePoint列表上。显示成那个样子没有问题,但是在排序和筛选的时候就有问题了。不知道那些文章的作者是否试过绑定SharePoint列表,反正在我这里用无代码方式是不能进行筛选的(排序似乎OK)。处理筛选的时候,一般介绍的方法是指定SPGridView的FilteredDataSourcePropertyName属性为“FilterExpression”、指定FilteredDataSourcePropertyFormat属性为“{1}='{0}'”,但是这种方法对于数据源为SPDataSource的SharePoint列表绑定是行不通的,因为SPDataSource并没有FilterExpression这个属性,也没有任何和筛选相关的属性,我也没找到其他解决筛选的方法。从这一点看来,我觉得SPDataSouce并不是一个完善的数据源实现,不知道在2009中会不会有改进。
其实解决SharePoint列表数据绑定的方法也很简单,那就是先把列表数据转换成DataTable(通过SPListItemCollection的GetDataTable方法),再用ObjectDataSource作为数据源绑定到SPGridView上,这样就可以实现不写代码的排序和筛选了(不过也有一些不如用SPDataSource的地方,放到后面再说)。
先来说筛选,关于SPGridView的筛选问题网上几乎所有的文章都提到了这一篇:Filtering with SPGridView。这篇文章主要说的内容有两点:第一、在SPGridView绑定的时候,如果希望实现筛选功能,那么在绑定时需要指定SPGridView的DataSourceID为ObjectDataSource的ID,而不能直接将DataSource指定为ObjectDataSouce;第二、默认情况下SPGridView的筛选和排序同时进行的时候会有问题(显示不合逻辑),文中给出了一种使用ViewState保存筛选条件的解决方案,在这里就不再赘述了。
然后说说数据绑定问题,SPGridView是不支持自动生成绑定列的,所以必须把AutoGenerateColumn设成false。一般我们在写asp.net的时候,绑定数据列使用BoundField控件,在SharePoint中有一个更好的选择,那就是SPBoundField。它的使用方法和BoundField完全一致,但是它对SharePoint的数据类型(也就是栏类型)做了处理,对超链接、多选、查阅项等内容都有比较好的处理,它的底层是调用了对应SPField的GetFieldValueAsHtml方法(所以,如果你希望这个东西能很好地显示你的自定义字段类型,你最好在实现自定义字段的时候把GetFieldValueAsHtml重写)。当然,这个所谓的“比较好的处理”指的是使用SPDataSource作为数据源。当我们使用ObjectDataSource绑定用GetDataTable方法获得的DataTable时,问题就出现了:多选项不能正常显示为多选(而是;#那种内部表示)、超链接不能显示为链接(显示为“url,说明”)、人员没有链接、最不能忍受的是多行文本都不是以html形式显示的,这是因为在GetDataTable的时候,SharePoint就已经做过一次数据转换了,即使用SPBoundField绑定,也会有问题。解决方法也有,就是实现一个自己的GetDataTable……其实也不麻烦。
最后,SPGridView是继承了GridView的,所以可以加“选择”功能,直接在最后加一列CommandField就行了。也可以通过一些trick的方法把选择按钮隐藏掉,然后实现单击一行的时候选中,比如下图:
当然,既然是继承了GridView,也可以做一些其他操作,比如加个按钮什么的。但是另一个问题又出现了,SPGridView在按钮列(或者那种下拉菜单)PostBack的时候,数据绑定失败。也有解决方案:SPGridView, SPMenuField, Grouping, Postback。