GridView 和 FormView 的结合方式,为我们呈现数据列和编辑一个数据行带来了极大的方便。可非常不幸的是,当 DataSourceControl 没有从数据库中取到任何数据时,GridView 的整个 table 在最终呈现的 HTML 中是不存在的,无论怎样 ShowFooter 和 ShowHeader 都没有办法让它出现。
曾经想过使用 EmptyDataTemplate,然后画一张与 GridView 一样的表来让它出现。但这种做法相当不优雅,尤其是当你使用了排序功能和 HeaderTemplate or FooterTemplate 的情况下。而且你也不得不为它们应用同样的 CSS。一旦你改变了 GridView 的 Header 或 Footer,你也不得不在 EmptyDataTemplate 中应用同样的更改。
继承 GridView 生成新的控件的方法,确实能够解决问题,但实现起来非常麻烦。
当然,使用 DataSet 而不是 DataSourceControl 的朋友要方便得多,他们只需要在 DataSet 中 Rows.Count 为 0 时主动产生一个新行就可以了,可是这并不能成为我们要放弃 DataSourceControl 使用 DataSet 的理由。那么,如何让 GridView 在无数据时显示表头呢?
我的思路是,使用 DataView 来向 GridView 插入一个空行,并使 Visible = false。不过,在不继承 GridView 或 SqlDataSource 的情况下要拿到 DataView 可不是一件容易的事,所幸我在 MSDN 中有关 SqlDataSource 的 public 函数 Select 中找到了这样的说明:
“在页生命周期的 PreRender 阶段中会自动调用 Select 方法。该方法由已通过其 DataSourceID 属性附加到 SqlDataSource 控件的数据绑定控件调用。
如果 DataSourceMode 属性设置为 DataSet 值,则 Select 方法会返回 DataView 对象。如果 DataSourceMode 属性设置为 DataReader 值,则 Select 方法会返回 IDataReader 对象。数据读取完毕后,关闭 IDataReader 对象。”
呃,好极了!那么剩下的事情就简单了,写一个通用函数,专门用来处理此类事宜:
然后在 GridView 进行数据绑定之前重新将 DataSource 置空(因为 ViewState 的关系,必须这么做!除非 GridView 的 EnableViewState 为 false),并为其设置 DataSourceID 让其从数据源控件中读数据。可用的地方除了 GridView 的 Load 事件就是 Page_Load 最佳了:
现在事情可以告一段落了。BUT……在哪里调用我们的 GridViewShowAt0Row 最合适呢?
数据绑定之前我们不知道 GridView 的行数,这显然不可行。我首先想到的是 GridView 的 DataBound 事件,但 IE 给了我一张黄脸告诉我:数据绑定其间不可再调用 DataBind 函数。
其次我又想到了 SqlDataSource 的 Selected 函数,结论是一样的。那么,最终的地方只有一个了:GridView 的 PreRender 事件:
总结:使用这个方法,最大的遗憾就是 GridViewShowAt0Row 会重复产生一次对数据库的 Select 操作。但这是没有办法的事,除非改用 DataSet 或继承 GridView。绑定的 SqlDataSource Mode 属性需要为 DataSet,DataReader 肯定不行。
还有,我没有为支持所有的 IDataSource 接口的组件提供支持——GridViewShowAt0Row 目前只能支持 SqlDataSource,如果要支持所有的 IDataSource,只需要使用 IDataSource.GetView 获得一个 DataSourceView,再通过 Select 并提供一个接收 IEnumerable 接口的委托的函数,然后将 IEnumerable 转化为相应的类型再添加数据即可。
最后,GridView 的 DataSourceObject 属性需要 .Net Framework 3.5 SP1 版本,不带 SP1 的版本是没有这个属性的,那就需要用 GridView.Page.FindControl 来找 SqlDataSource 控件了。
本文介绍了一种方法,可以在GridView未从数据库获取到数据时仍能显示表头。通过在GridView的PreRender事件中插入一个空行,并将其可见性设为false,实现了即使没有数据也能显示表头的需求。

3390

被折叠的 条评论
为什么被折叠?



