接着上篇介绍,上篇已经通过控件简单实现了排序的功能,下面让我们看看带有分页的排序该怎么做。
第五步: 为使用默认分页的数据列表添加排序的支持
打开分页排序数据列表转发器文件夹里的使用默认分页进行排序。文件和Paging.aspx页。在Paging.aspx页里查看源文件。将图8里选择的文本复制下来,然后粘贴到使用默认分页进行排序。文件页里的ASP :内容标签内。
图8: 复制粘贴代码
然后将Paging.aspx页后台代码里的属性和方法也粘贴到使用默认分页进行排序。文件页后台代码里。现在浏览使用默认分页进行排序。文件页,它现在应该有和Paging.aspx页一样的外观和功能。
在ProductsBLL里添加默认的分页和排序方法
前面一章里我们在ProductsBLL类里创建了一个GetProductsAsPagedDataSource(页面索引,页面大小)方法,它返回一个页面数据源对象。这个对象通过基地址定位连接的GetProducts()方法获取所有的产品,然而绑定到数据列表的只是那些和输入参数页面索引和页面大小相关的记录。
本章前面我们已经通过在对象数据源的选择事件处理程序里指定排序表达式来添加了排序功能。当对象数据源返回可排序对象时这个方法运转的很好,比如GetProducts()方法返回的产品数据表。然而GetProductsAsPagedDataSource方法返回的页面数据源对象并不支持对它内部数据的排序,因此我们需要在将数据放入页面数据源前对GetProducts()方法返回的记录进行排序。
在ProductsBLL类里建一个getproductsorted spaged数据源(排序表达式、页面索引、页面大小)方法。指定GetProducts()方法返回的产品数据表的默认数据表视图的排序属性。
[系统。组件模型组件模型。dataobjectmethodtype。选择,假)]公共页面数据源getproductsortedspagedata数据源(字符串sortExpression,int pageIndex,int pageSize){ //获取北风的所有产品产品数据表产品=GetProducts();//对产品进行分类产品。默认视图。排序=排序表达式;//通过页面限制结果页面数据源页面数据源页面数据源页面数据源=新页面数据源();页面数据。数据源=产品默认视图页面数据允许老化=真页面数据CurrentPageIndex=pageIndex页面数据。页面大小=页面大小;返回页面数据;} getproductsorted spaged数据源方法和前面一章里的GetProductsAsPagedDataSource方法有一点不一样getproductsorted spaged数据源。多了一个排序表达式参数,将它的值赋给ProductDataTable的默认视图的分类属性。并将ProductDataTable的默认视图赋给页面数据源对象的数据源。
调用getproductsorted spaged数据源方法并指定输入参数排序表达式的值
完成这些后,下一步需要提供参数值sorting withddefaultpaging . aspx页的对象数据源现在被配置用来调用GetProductsAsPagedDataSource方法并通过两个查询字符串参数来传递参数,这些参数在选择参数集合里已经指定了。这两个查询字符串参数参数表示GetProductsAsPagedDataSource方法的页面索引和页面大小参数从参数里获取。
修改对象数据源的选择方法属性,让它调用getproductsorted spaged数据源方法。然后添加一个新的QueryStringParameter来让排序表达式参数通过参数的排序表达式字段获取。将QueryStringParameter的默认值设为产品名称。
现在对象数据源的声明标记语言看起来应该和下面差不多:
ASP : object data source ID=' productdefaultpaging data source ' oldvaluesparametertformatstring=' original _ { 0 } ' TypeName=' products bll ' SelectMethod=' getproductsultsorted spaged data source ' on Selected=' productdefaultpaging data source _ Selected ' runat=' server ' SelectParameters as :查询字符串参数DefaultValue=' product ' Name=' sort expression '查询字符串=' sort expression ' Type=' String '/asp3:查询字符串参数DefaultValue现在使用默认分页进行排序。文件页会按照产品名称的字母顺序排序。见图9。这是因为getproductsorted spaged数据源方法的排序表达式参数的默认值为产品名称。
图9: 默认的按照商品名称排序
如果你手动添加一个排序表达式查询字符串字段比如SortingWithDefaultPaging.aspx?排序表达式=CategoryName那么结果会以指定的排序表达式来排序。然而在转到另外一个页时这个排序表达式参数并没有包含在参数里。实际上当点上或者下一页时我们会返回Paging.aspx。而且当前并没有排序界面。用户可以改变数据排序的唯一方法是直接操作询问。
创建排序界面
我们首先要修改重定向用户方法来将用户重定向到使用默认分页进行排序。文件页(而不是Paging.aspx),并将排序表达式的值包含到参数里。我们还应该添加一个只读的排序表达式属性。这个属性和前面一章里创建的页面索引和页面大小属性相似,在排序表达式查询字符串字段存在时返回它的值,否则的话使用默认值产品名称。
现在的重定向用户方法只接收一个参数显示的页的指数。然而可能有些时候我们需要使用排序表达式将用户重定向到特定数据的页。我们将马上来为这个页创建排序界面,它将包含一些按钮来为指定的列排序。当其中一个按钮被点击时,我们需要传入合适的排序表达式的值来重定向用户。为了提供这个功能,创建两个重定向用户方法。第一个接收页,面,张,版的指数,第二个接收页面索引和排序表达式(排序表达式)。
私有字符串SortExpression{ get { if(!字符串IsNullOrEmpty(请求. QueryString['sortExpression']))返回请求查询字符串['排序表达式'];否则返回”ProducT name”;} } private void RedirectUser(int sendsusertopageindex){//使用排序表达式属性从查询字符串RedirectUser(sendsusertopageindex,排序表达式)中获取排序表达式//;} private void RedirectUser(int sendsusertopageindex,string sendsusersortingby){//使用请求的排序表达式反应将用户发送到请求的页面。重定向(字符串. format(' sortingWithDefaultPaging。aspx?页面索引={ 0 }页面大小={ 1 }排序表达式={ 2 } ',sendUserToPageIndex,页面大小,sendsusersortingby));}本章的第一个例子里,我们使用控件来创建了一个排序界面。我们将在这个例子里使用3个按钮(它们位于数据列表上方)一个表示为商品名称排序,一个为类别名称,一个为供应商名称。添加三个按钮并设置它们的身份和正文。
p asp:按钮runat=' server ' id=' sortbyProductName ' Text='按产品名称排序/asp3360按钮runat=' server ' id=' sortbycategory Name ' Text='按类别排序/asp3360按钮runat=' server ' id=' SortBySupplierName ' Text='按供应商排序/p然后为每个按钮创建一个单击事件处理程序。这个事件处理将调用重定向用户方法,并使用合适的排序表达式将用户返回到第一页。
受保护的void SortByProductName_Click(对象发送者,事件参数e){ //按ProductName RedirectUser(0,' ProductName ')排序;}受保护的void SortByCategoryName_Click(对象发送方,事件参数e){ //按类别名称重新排序用户(0,‘类别名称’);}受保护的void SortBySupplierName_Click(对象发送者,事件参数e){ //按SupplierName RedirectUser(0,' SupplierName ')排序;}第一次浏览页面时,数据会按照产品名称的字母顺序排序(见图9)。单击“下一步”按钮浏览第二页,然后单击“按类别排序”按钮。这将使页面返回到第一页,并按类别名称排序,如图10所示。同样,点击“按供应商排序”按钮,将根据供应商对数据进行排序,并返回第一页。当数据被分页时,排序的选择将被记录。图11示出了按类别排序和浏览第十三页。
图10:按类别分类的产品。
图11:分页时将记录排序表达式。
第六步:定制:直放站的寻呼。
步骤5中的数据列表示例使用了默认的分页技术。当有大量数据时,我们需要使用自定义分页。回到高效分页大型数据事件和排序自定义分页数据,我们了解了默认和自定义分页方法之间的区别,并在BLL创建了自定义分页和排序自定义分页数据的方法。在这两章中,我们在ProductsBLL中添加了以下三种方法:
Getproductspaced (startRowIndex,maximumRows)返回一个不超过起始RowIndex最大行数的特定记录集。getproductpagesandsorted(sortExpression,起始行索引,最大行数)基于指定的sort expression返回特定的记录集。TotalNumberofProducts()提供产品表中记录的总数。
这些方法可用于数据列表或中继器中的高效分页和排序。首先,我们创建一个支持自定义分页的Repeater。然后添加排序支持。打开分页排序数据列表转发器文件夹下的排序与自定义分页. aspx页面,添加一个转发器,并将标识设置为产品。从智能标记创建名为产品数据源的对象数据源。使用ProductsBLL类的GetProductsPaged方法配置其选择标签。
图12:配置对象数据源。
在更新、插入、删除选项卡中选择“(无)”,然后单击下一步。现在我们需要为GetProductsPaged方法的startRowIndex和maximumRows参数选择源。其实这里不需要配置。这两个参数的值将由ObjectDataSource的select事件处理程序中的Arguments属性指定,就像我们在本章的第一个示例中指定的sortExpression一样。因此,在参数源的下拉列表中选择“无”。
图13:将参数源设置为“无”。
注意:不要将对象数据源的启用分页属性设置为真。这样,对象数据源将自动将其起始行索引和最大行参数包含在选择方法的现有参数列表中。EnablePaging属性仅在将自定义分页数据绑定到GridView、DetailsView、FormView时有用。由于我们手动添加了对DataList和Repeater的分页支持,我们将它们设置为false(默认),我们将在ASP.NET页面中直接实现这些功能。
最后,定义Repeater的ItemTemplate,使其只显示产品的名称、类别、供应商。完成此操作后,Repeater和ObjectDataSource的声明语言应该类似于以下内容:
asp3360中继器ID=' Products ' runat=' server ' DataSourceID=' Products data source ' EnableViewState=' False '项目模板H4 asp:标签ID=' productnamelab ' runat=' server ' Text=' % # Eval('产品名称' %)'/asp3360标签/H4 category3360标签ID=' categorynamelab ' runat=' server ' Text=' % # Eval(' categorname ')% %现在浏览该页,注意没有返回任何记录。这是因为我们还没有指定startRowIndex和最大行数参数的值。为了指定这些值,为对象数据源的选择事件创建一个事件处理程序,并将参数值硬编码的设置为0和5。
受保护的作废产品数据源_选择(对象发送者,对象数据源选择事件参数){ e . InputParameters[' startrow index ']=0;e . InputParameters[' maximumRows ']=5;}现在浏览页面时会显示前5条产品记录。
图14: 显示前5条产品
注意:图14列出的制品以产品名称排序是因为自定义分页使用的GetProductsPaged存储过程返回的结果是以商品名称排序。
为了让用户可以翻页,我们需要在回发过程中记下开始行索引和最大行数。在默认分页的例子里我们用参数来保存这些值。这个例子里我们将使用查看状态。创建下面两个属性:
private int startrownindex { get { object o=ViewState[' startrownindex '];if (o==null)返回0;否则返回(int)o;}设置{ ViewState[' startrownindex ']=值;} } private int MaximumRows { get { object o=ViewState[' MaximumRows '];if (o==null)返回5;否则返回(int)o;}设置{视图状态['MaximumRows']=值;}}然后更新选择事件处理程序的代码,使用StartRowIndex和最大行数属性代替硬编码的0和5。
e.InputParameters[' startrow index ']=startrow index;e . InputParameters[' maximumRows ']=maximumRows;现在我们的页仍然只显示5条记录。然而完成这些属性后,我们已经可以创建分页界面了。
添加分页界面
我们还是使用和默认分页例子里一样的第一个、上一个、下一个、最后一个分页界面,并包含显示当前是哪页和总页数的标签。在中继器下面添加四个按钮和一一个标签。
p asp3360按钮运行时间='服务器' ID='第一页' Text='第一页'/asp3360按钮运行时间='服务器' ID='上一页' Text='上一页'/asp3360按钮运行时间='服务器' ID='下一页' Text='下一页'/asp3360按钮运行时间='服务器' ID='最后一页' Text='最后一页'/PP asp3360标签运行时间='服务器' ID='当前标签成员'/ASPA然后为四个按钮创建单击事件处理程序。当其中一个按钮被点时,我们需要修改StartRowIndex并将数据重新绑定到复读机。第一,以前,和下一步按钮的代码都非常简单,但是对最后一个按钮来说,我们如何判断最后一页数据的开始行索引?为了计算出这个索引和判断然后和最后一个按钮是否应该使能够一样我们需要知道分页数据的总数。我们可以调用ProductsBLL类的totalnumberofproductions()方法来获取这个总数。我们来创建一个只读的属性,名为TotalRowCount,它返回totalnumberofproductions()方法的结果。
private int TotalRowCount{ get { //从TotalNumberOfProducts()方法返回值ProductBLl ProductAPI=new ProductBLl();返回productsAPI。totalnumberofprudcts();}}有了这个属性,我们现在可以得到最后一页的起始行索引。它可以通过将TotalRowCount结果的整数部分除以MaximumRows并乘以MaximumRows来获得。现在我们可以为4个分页接口的按钮编写Click事件处理程序。
最后,在浏览第一页时需要禁用“第一个”和“上一个”按钮,在浏览最后一页时需要禁用“下一个”和“最后一个”按钮。在对象数据源的选择事件处理程序中添加以下代码:
//如果需要,禁用分页界面按钮。Enabled=StartRowIndex!=0;上一页。Enabled=StartRowIndex!=0;int lastpagestartrownindex=((TotalRowCount-1)/MaximumRows)* MaximumRows;下一页。enabled=startrownindex lastpagestartrownindex;最后一页。enabled=startrownindex lastpagestartrownindex;
完成后,浏览页面。参见图15。第一次浏览页面时,“第一个”和“上一个”按钮被禁用。单击“下一步”在第二页显示数据。单击最后显示最后一页的数据(见图16和17)。浏览最后一页时,“下一页”和“最后一页”按钮被禁用。
图15:浏览第一页时,上一个和最后一个按钮被禁用。
图16:第2页数据。
图17:的最后一页。
编程快乐!
作者简介
Scott Mitchell,本系列教程的作者,也是关于ASP/ASP的六本书的作者。NET,是4GuysFromRolla.com的创始人,自1998年以来一直使用微软的网络技术。你可以点击查看所有教程《[翻译]Scott Mitchell 的ASP.NET 2.0数据教程》,希望能帮助你学习ASP.NET。