下面是由ClientPageDataGrid控件实现的同一个页面:
<tr>
<td colspan="3">
<a href="javascript:__onPrevPage (''MyDataGrid'');"><</a>
<a href="javascript:__onNextPage (''MyDataGrid'');">></a>
</td>
</tr>
当ClientPageDataGrid.OnPreRender调用Page.RegisterClientScriptBlock时,导航标记所指向的JavaScript函数就被打上标记。调用RegisterClientScriptBlock确保包括这些函数的脚本块仅仅被输出一次,甚至当页面包括ClientPageDataGrid的多个实例时也是这样。 逆风者
虽然ClientPageDataGrid并没有包括任何自己的服务器请求,但是页面的其他控件仍然会导致向服务器的请求。这产生了两个问题。第一,当请求发生时,ClientCurrentPageIndex应当进行更新,因此服务器端代码能决定哪一页被显示。第二,当页面从服务器反馈回后,ClientPageDataGrid应当能被当前页保存。用另外的话说就是,当第3页显示时向服务器请求时,ClientPageDataGrid的代码应当加入一个样式style="display:
block"给包括第3页的<DIV>模块,而其他<DIV>模块没有。
为解决这些问题,ClientPageDataGrid注册了一个隐含字段controlid__ PAGENUM:
Page.RegisterHiddenField (ClientID "__PAGENUM",
ClientCurrentPageIndex.ToString ());
当页面更新时,在客户端中通过输出页面进行分页的JavaScript函数来更新隐含的字段。当页面请求发给服务器后,隐含字段的值被加入到服务器返回数据中。ClientPageDataGrid的LoadViewState方法从返回的数据中读取这个值,并且通过RestoreCurrentPageIndex方法设置ClientCurrentPageIndex的值,代码如下:
string page = Page.Request[ClientID "__PAGENUM"];
...
ClientCurrentPageIndex = Convert.ToInt32 (page);
请求时间处理代码能通过ClientCurrentPageIndex属性的值判断用户要读取哪一页。同时因为ClientPageDataGrid.Render使用ClientCurrentPageIndex来判断哪一个<DIV>被显示,因此当前显示页直到页面数据请求发生后才隐藏。
在LoadViewState带来的反馈数据中包括当前页索引非常有用。首先,当前页的索引不会被设置直到控件被组装,存在LoadViewState中。此外,由于LoadViewState在主页的装入事件触发前被调用,Page_Load方法能通过ClientCurrentPageIndex属性值来判断用户的当前页的索引。那样是非常重要的,因为当前页的索引会带来其他的变化。
RestoreCurrentPageIndex同样被ClientPageDataGrid的DataBind方法调用,而且仅仅是,如果不是被LoadViewState调用的话。为什么呢?因为如果视图状态被禁用了(即EnableViewState=false),则LoadViewState就不能被ASP.NET运行库调用。如果视图状态被禁用,页面就会调用DataBind重新装载控件,因此调用DataBind方法就是根据返回数据恢复当前页的索引就很自然了。
或许你注意到了ClientPageDataGrid的DataBind方法调用绑定数据并不是一次,而是两次(见Figure
10)。第1次调用是基类的DataBind方法给ClientPageDataGrid提供记录条数,产生一个包括所有数据的DataGrid。DataGrid放在ClientPageDataGrid下面,为描述数据源提供服务。
ClientPageDataGrid的DataBing方法另一个特别的地方是它将DataReaders转变为DataSets.。有两个理由这么做。首先,DataReader只能被绑定一次,因为它是只能向前读取的数据源。其次,通常的DataGrid并不支持DataReaders作为数据源,如果AllowPaging值为true的话,直到AllowCustomPaging也为true时才行。在程序内部巧妙地将DataReaders转换为DataSets就解决了这些问题,并且确保ClientPageDataGrid工作起来像使用DataReaders一样,而实际上是在使用DataSets。 本文章更多内容:<<上一页 - 1 - 2 - 3 - 4 - 下一页>> |