宜城网站定制,赣州编程培训机构,天眼查企业查询官网登录,著名设计师网站原文 | 下载本教程中的编码例子 | 下载本教程的PDF版 导言 分页和排序是显示数据时经常用到的功能。比如#xff0c;在一个在线书店里搜索关于ASP.NET 的书的时候#xff0c;可能结果会是成百上千#xff0c;而每页只列出十条。而且结果可以根据title#xff08;书名#…原文 | 下载本教程中的编码例子 | 下载本教程的PDF版 导言 分页和排序是显示数据时经常用到的功能。比如在一个在线书店里搜索关于ASP.NET 的书的时候可能结果会是成百上千而每页只列出十条。而且结果可以根据title书名price价格page count页数author name作者等来排序。我们在分页和排序报表数据 里已经讨论过 GridView, DetailsView, 和FormView 都有内置的分页功能仅仅只需要勾一个checkbox就可以开启。GridView 还支持内置的排序。 不幸的是DataList 和Repeater 都没有提供内置的分页和排序功能。本章我们将学习如何在DataList 和Repeater 里添加分页和排序的支持。我们需要创建分页界面显示正确的页的记录并在postback过程中记下浏览的页。虽然这会比GridView, DetailsView, 和FormView里花费更多的时间和写更多的代码但是也提供了更多的可扩展性。 注意本章集中精力讨论分页下章我们将学习排序。 第一步: 添加分页和排序的教程页 首先添加本章和下一章需要的页。创建一个名为PagingSortingDataListRepeater的文件夹然后添加下面的5个页记得全部选择Site.master。 Default.aspx Paging.aspx Sorting.aspx SortingWithDefaultPaging.aspx SortingWithCustomPaging.aspx 图 1: 创建页 然后打开Default.aspx页从UserControls文件夹里拖一个SectionLevelTutorialListing.ascx用户控件进来。这个用户控件我们已经用了很多次了。见母板页和站点导航 。 图 2: 添加用户控件 为了将排序和分页的教程列出来我们需要将他们添加到site map站点地图里。打开Web.sitemap文件将下面的标记语言添加到“Editing and Deleting with the DataList”的节点后面 XML 12345678910111213141516171819202122232425 siteMapNodeurl~/PagingSortingDataListRepeater/Default.aspxtitlePaging and Sorting with the DataList and RepeaterdescriptionPaging and Sorting the Data in the DataList and Repeater ControlssiteMapNodeurl~/PagingSortingDataListRepeater/Paging.aspxtitlePagingdescriptionLearn how to page through the data shownin the DataList and Repeater controls. /siteMapNodeurl~/PagingSortingDataListRepeater/Sorting.aspxtitleSortingdescriptionSort the data displayed in a DataList orRepeater control. /siteMapNodeurl~/PagingSortingDataListRepeater/SortingWithDefaultPaging.aspxtitleSorting with Default PagingdescriptionCreate a DataList or Repeater control that is paged usingdefault paging and can be sorted. /siteMapNodeurl~/PagingSortingDataListRepeater/SortingWithCustomPaging.aspxtitleSorting with Custom PagingdescriptionLearn how to sort the data displayed in a DataList orRepeater control that uses custom paging. //siteMapNode 图 3: 更新 Site Map 回顾一下分页 在前面我们学习了如何使用GridView, DetailsView, FormView 来分页。这三个控件都提供了一种称为默认分页的功能仅仅只需要从智能标签里勾上“Enable Paging”开启分页即可。在使用默认分页时每次请求数据 – 无论是第一页还是其它页–GridView, DetailsView, 和FormView 都会重新请求所有的数据。然后根据请求的页索引和每页显示的记录数来显示特定页的数据而忽略其它数据即虽然被请求但未显示的数据。我们在分页和排序报表数据 里已经详细的讨论过默认分页了。 默认分页由于每次都请求所有的数据因此在大数据量的情况下并不合适。例如想象一下每页显示10条数据总共有有50,000条。每次用户浏览一页时都要从数据库请求50,000条数据而其中只有10条会被显示。 自定义分页使用每次只返回请求的数据从而解决了默认分页的性能问题。当使用自定义分页时我们需要写有效的返回正确的记录的SQL语句。我们在里学习了用SQL Server2005的ROW_NUMBER() keyword 来创建这样的语句。 在DataList或Repeater里使用默认分页我们可以使用PagedDataSource class来包装ProductsDataTable里需要分页的内容。PagedDataSource类有一个可以赋给任何枚举类型对象的DataSource属性和PageSize 每页显示的记录数and CurrentPageIndex 当前页的索引。一旦设置了这些属性PagedDataSource就可以作为任何数据控件的数据源。PagedDataSource根据PageSize和CurrentPageIndex来返回合适的记录。图4描述了PagedDataSource类的功能。 图 4: PagedDataSource使用可分页的界面包装枚举对象 PagedDataSource对象可以在BLL里直接创建和配置并通过ObjectDataSource绑定到DataList或Repeater。或者也可以在ASP.NET 页的后台代码里直接做这些。如果使用后一种方法我们就不能使用ObjectDataSource而应该直接编程将分页数据绑定到DataList或Repeater。 PagedDataSource对象也有支持自定义分页的属性。但是在这里我们将不讨论它因为我们在ProductsBLL类里已经有一个可以精确的返回需要显示的记录的方法。 本章我们将学习如何通过在ProductsBLL类里添加一个返回合适的PagedDataSource对象的方法来实现默认分页。下章我们再讨论自定义分页。 第二步: 在BLL里添加默认的分页方法 ProductsBLL类里现在有一个返回所有product的方法–GetProducts()–和一个返回特定子集的方法–GetProductsPaged(startRowIndex,maximumRows)。当使用默认分页时GridView, DetailsView, FormView 使用GetProducts()方法获取所有的product但是在内部使用PagedDataSource来显示正确的记录子集。在DataList和Repeater里实现同样的功能我们可以在BLL里创建一个模拟这种行为的方法。 在ProductsBLL里添加一个带两个整型参数的方法名为GetProductsAsPagedDataSource pageIndex – 显示的页的索引从0开始 pageSize – 每页显示的记录数. GetProductsAsPagedDataSource首先从GetProducts()里获取所有的记录。然后创建一个PagedDataSource对象将CurrentPageIndex和PageSize属性设置为传进来的参数pageIndex和pageSize。方法的最后返回这个配置过的PagedDataSource。 C# 12345678910111213141516 [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, false)]public PagedDataSource GetProductsAsPagedDataSource(int pageIndex, int pageSize){// Get ALL of the productsNorthwind.ProductsDataTable products GetProducts();// Limit the results through a PagedDataSourcePagedDataSource pagedData new PagedDataSource();pagedData.DataSource products.Rows;pagedData.AllowPaging true;pagedData.CurrentPageIndex pageIndex;pagedData.PageSize pageSize;return pagedData;} 第三步: 在DataList里使用默认分页显示Product 完成GetProductsAsPagedDataSource方法后我们现在来创建一个提供默认分页的DataList或Repeater。打开PagingSortingDataListRepeater文件夹下的Paging.aspx页拖一个DataList进来将ID设为ProductsDefaultPaging。通过智能标签创建一个名为ProductsDefaultPagingDataSource的ObjectDataSource并用GetProductsAsPagedDataSource方法配置它。 图 5: 创建并配置ObjectDataSource 在UPDATE, INSERT, DELETE 标签的下拉列表里都选择“(None)”. 图 6: 在UPDATE, INSERT, DELETE 标签的下拉里选择“(None)” 因为GetProductsAsPagedDataSource方法需要两个参数因此向导会提示我们选择参数源。 page index和page size的值必须在postback过程中记下来。它们可以存在view statequerystringsession里或用其它技术来记录。本章我们使用querystring。 分别使用querystring字段“pageIndex” 和“pageSize”来配置pageIndex和pageSize。见图7。由于用户第一次浏览页的时候没有querystring因此还需要设置这两个参数的默认值。将pageIndex的默认值设为0表示显示第一页数据将pageSize的默认值设为4。 图 7: 配置参数 配置完ObjectDataSource后Visual Studio自动为DataList创建一个ItemTemplate。修改它让它只显示product的namecategory和supplier。将DataList的RepeatColumns属性设为2Width设为“100%”, ItemStyle的Width设为 “50%”. 这样的设置会为两列提供相同的间距。 完成这些后DataList和ObjectDataSource的标记语言看起来应该如下 ASP.NET 12345678910111213141516171819202122232425262728 asp:DataList IDProductsDefaultPaging runatserver Width100%DataKeyFieldProductID DataSourceIDProductsDefaultPagingDataSourceRepeatColumns2 EnableViewStateFalseItemTemplateh4asp:Label IDProductNameLabel runatserverText%# Eval(ProductName) %/asp:Label/h4Category:asp:Label IDCategoryNameLabel runatserverText%# Eval(CategoryName) %/asp:Labelbr /Supplier:asp:Label IDSupplierNameLabel runatserverText%# Eval(SupplierName) %/asp:Labelbr /br /br //ItemTemplateItemStyle Width50% //asp:DataListasp:ObjectDataSource IDProductsDefaultPagingDataSource runatserverOldValuesParameterFormatStringoriginal_{0} TypeNameProductsBLLSelectMethodGetProductsAsPagedDataSourceSelectParametersasp:QueryStringParameter DefaultValue0 NamepageIndexQueryStringFieldpageIndex TypeInt32 /asp:QueryStringParameter DefaultValue4 NamepageSizeQueryStringFieldpageSize TypeInt32 //SelectParameters/asp:ObjectDataSource 注意由于这里我们不实现任何更新或删除的功能你可以禁用DataList的view state来减少页面的大小。 第一次浏览页的时候querystring里没有提供pageIndex 和pageSize的值因此将使用默认的0和4。见图8。DataList将显示4条product记录。 图 8: 显示4条Product 由于还没有分页的界面因此用户现在还不能直接导航到第二页。我们将在第四步里创建分页界面。现在我们只能直接在querystring里指定分页的参数来进行分页。例如我们可以将地址从Paging.aspx改为Paging.aspx?pageIndex2然后回车来浏览第二页。这样就可以看到第二页的数据了见图9。 图 9: 显示第二页数据 第四步: 创建分页界面 有很多不同的完成分页界面的方法。GridView, DetailsView, FormView 提供了4种不同的界面 Next, Previous后一页前一页 – 用户可以浏览上一页或下一页. Next, Previous, First第一页, Last 最后一页– 除了上面的功能这个还包含第一页和最后一页。 Numeric 数字–在分页界面上列出页数用户可以随意的选择一个页 . Numeric, First, Last – 在上一个功能的基础上增加了第一页和最后一页. 对DataList 和Repeater而言我们需要决定它的分页界面并实现它。这其中包含了需要创建web控件和当特定页的button被点时显示请求的页。另外某些分页界面的控件可能需要禁用。例如当使用Next, Previous, First, Last这个模式来显示时如果浏览第一页数据那么第一页和前一页的button应该被禁用。 本章我们使用 Next, Previous, First, Last界面。添加4个button并将ID分别设为FirstPage,PrevPage,NextPage和LastPage。将Text设为“ First”, “ Prev”, “Next ”, “Last ”. ASP.NET 1234 asp:Button runatserver IDFirstPage Text First /asp:Button runatserver IDPrevPage Text Prev /asp:Button runatserver IDNextPage TextNext /asp:Button runatserver IDLastPage TextLast / 然后为每个button创建一个Click事件处理。呆会我们将添加代码来显示请求的页。 记下分页的总记录数 不管选择哪种分页界面我们都需要计算和记下分页的总记录数。总的行数和page size来决定总的页数它决定了那些分页界面的控件需要增加或启用。在我们创建的Next, Previous, First, Last 界面里page count页数在两种情况下需要被用到 判断我们是否在浏览最后一页这种情况下Next 和Last buttons 需要禁用。 如果用户点了Last button我们需要将它转到最后一页它的索引等于page count减1。 page count通过总行数除以page size页数来计算得到。例如我们要分页79条记录每页显示4条那么page count为2079/4。如果我们使用数字分页界面就可以通过这个信息来决定要显示多少个数字页的button。如果分页界面只包含Next 和Last buttons可以通过page count来什么时候禁用Next 和Last buttons。 如果分页界面包含Last button最后一页我们需要在postback过程中记下分页的总记录数这样在点Last button的时候我们可以获得最后一页的索引。为了方便实现这个我们在ASP.NET页的后台代码里创建一个TotalRowCount属性来将这个值保存到view state里。 C# 123456789101112131415 private int TotalRowCount{get{object o ViewState[TotalRowCount];if (o null)return -1;elsereturn (int)o;}set{ViewState[TotalRowCount] value;}} 除了TotalRowCount外还需要为page indexpage size和page count创建页面级的只读属性来方便读取。 C# 1234567891011121314151617181920212223242526272829 private int PageIndex{get{if (!string.IsNullOrEmpty(Request.QueryString[pageIndex]))return Convert.ToInt32(Request.QueryString[pageIndex]);elsereturn 0;}}private int PageSize{get{if (!string.IsNullOrEmpty(Request.QueryString[pageSize]))return Convert.ToInt32(Request.QueryString[pageSize]);elsereturn 4;}}private int PageCount{get{return (TotalRowCount / PageSize) 1;}} 获取分页的总记录数 从ObjectDataSource的Select()方法返回一个PagedDataSource对象包含所有的product记录即使只有一部分会在DataList里显示。PagedDataSource的Count property 返回将在DataList里显示的项的数目。DataSourceCount property 返回PagedDataSource里的所有项的的总数目。因此我们需要将ASP.NET页的TotalRowCount属性赋值为PagedDataSource的DataSourceCount。 我们为ObjectDataSource的Selectd事件创建一个event handler来完成这些。在Selectd的event handler里我们获取ObjectDataSource的Select()方法的返回值–在这种情况下是PagedDataSource。 C# 12345678910 protected void ProductsDefaultPagingDataSource_Selected(object sender, ObjectDataSourceStatusEventArgs e){// Reference the PagedDataSource bound to the DataListPagedDataSource pagedData (PagedDataSource)e.ReturnValue;// Remember the total number of records being paged through // across postbacksTotalRowCount pagedData.DataSourceCount;} 显示请求的页的数据 当用户点分页界面上的button时我们需要显示请求的页的数据。由于分页的参数在querystring里指定因此使用Response.Redirect(url)来让用户重新请求带合适分页参数的Paging.aspx页。例如显示第二页的数据我们将用户重定向到Paging.aspx?pageIndex1。 创建一个RedirectUser(sendUserToPageIndex)方法来重定向用户到Paging.aspx?pageIndexsendUserToPageIndex。然后在四个按钮的Click事件处理里调用这个方法。在FirstPageClick里调用RedirectUser(0)在PrevPageClick里调用RedirectUserPageIndex-1。 C# 123456789101112131415161718192021222324252627282930 protected void FirstPage_Click(object sender, EventArgs e){// Send the user to the first pageRedirectUser(0);}protected void PrevPage_Click(object sender, EventArgs e){// Send the user to the previous pageRedirectUser(PageIndex - 1);}protected void NextPage_Click(object sender, EventArgs e){// Send the user to the next pageRedirectUser(PageIndex 1);}protected void LastPage_Click(object sender, EventArgs e){// Send the user to the last pageRedirectUser(PageCount - 1);}private void RedirectUser(int sendUserToPageIndex){// Send the user to the requested pageResponse.Redirect(string.Format(Paging.aspx?pageIndex{0}pageSize{1},sendUserToPageIndex, PageSize));} 完成Click事件处理后DataList的记录现在可以通过button来分页了你可以测试一下。 禁用分页控件 现在无论浏览哪页四个按钮都是可用的。然而我们在浏览第一页时需要禁用 First 和Previous buttons 在浏览最后一页时需要禁用Next 和Last buttons。通过ObjectDataSource的Select()方法返回的PagedDataSource对象有几个属性– IsFirstPage 和 IsLastPage –通过它们可以判断用户浏览的是否是第一或最后一页数据。 添加下面的代码到ObjectDataSource的Selected事件处理里 C# 123456 // Configure the paging interface based on the data in the PagedDataSourceFirstPage.Enabled !pagedData.IsFirstPage;PrevPage.Enabled !pagedData.IsFirstPage;NextPage.Enabled !pagedData.IsLastPage;LastPage.Enabled !pagedData.IsLastPage; 添加完后当浏览第一页时First 和Previous buttons 将被禁用。当浏览最后一页时Next 和 Last buttons 将被禁用。 我们最后来实现在分页界面里通知用户他们当前是浏览的哪页和一共有多少页。添加一个Label控件并将ID设为CurrentPageNumber。在ObjectDataSource的Selected事件处理中设置它的Text属性让它显示当前浏览的页PageIndex1和总页数PageCount。 C# 123 // Display the current page being viewed...CurrentPageNumber.Text string.Format(You are viewing page {0} of {1}...,PageIndex 1, PageCount); 图10是第一次浏览Paging.aspx页的样子。由于querystring是空的因此DataList默认显示最开始的4条product。First 和Previous buttons 被禁用。点Next 会显示下面的4条记录见图11而First 和Previous buttons 同时被启用了。 图 10: 第一页数据 图 11: 第二页数据 注意分页界面可以进一步改善比如增加允许用户来指定每页显示多少记录。例如添加一个DropDownList列出page size的选项比如5, 10, 25, 50, 和ALL。用户选择了page size后会重定向到Paging.aspx?pageIndex0pageSizeselectedPageSize。我将这个作为练习留给读者自己完成。 使用自定义分页 DataList使用没有效率的默认分页技术。当大数据量时我们需要使用自定义分页。虽然实现的细节有所不同但是分页里的概念和默认分页是一样的。默认分页时使用ProductsBLL类的GetProductsPaged方法而不是GetProductsAsPagedDataSource。正如在大数据量时提高分页的效率 里讨论的那样GetProductsPaged需要传入开始行的索引和行的最大数目。这些参数可以通过默认分页里使用的querystring里的pageIndex和pageSize参数来保存。 由于自定义分页里没有PagedDataSource所以需要其它技术来决定总记录数和判断我们是否显示第一或最后一页数据。ProductsBLL类的TotalNumberOfProducts()方法返回roduct的总记录数。而为了判断是否浏览的是第一页数据我们需要检查开始行的索引–如果是0则表示在浏览第一页。如果开始行的索引加上最大的行数大于或等于总记录数则表示在最后一页 我们将在下章详细的讨论如何实现自定义分页。 总结 DataList和Repeater都没有提供象GridView, DetailsView, FormView 那样的分页的支持这样的功能需要我们来实现。最简单的实现方法是使用默认分页将所有的product都包装到PagedDataSource里然后绑定PagedDataSource到DataList或Repeater。本章我们在ProductsBLL类里添加了GetProductsAsPagedDataSource方法它返回PagedDataSource。ProductsBLL类已经包含了自定义分页需要的方法– GetProductsPaged和TotalNumberOfProducts。 不管是自定义方法里获取精确的记录还是默认方法里获取所有记录我们都需要手动添加分页界面。本章我们创建的是包含4个button控件的Next, Previous, First, Last interface 。当然还添加了一个显示当前页和总页数的Label控件。 下章将学习如何为DataList和Repeater提供排序功能。我们也会创建一个既支持分页又支持排序的DataList和使用默认和自定义分页的例子 祝编程愉快! 转载于:https://www.cnblogs.com/Fernando/archive/2007/11/08/953225.html