让 GridView 在没有数据时显示 HeaderRow 和 FooterRow

本文介绍了一种方法,可以在GridView未从数据库获取到数据时仍能显示表头。通过在GridView的PreRender事件中插入一个空行,并将其可见性设为false,实现了即使没有数据也能显示表头的需求。

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 控件了。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值