在ASP.NET 2.0中操作數(shù)據(jù)之四十一:DataList和Repeater數(shù)據(jù)分頁(yè)
導(dǎo)言
分頁(yè)和排序是顯示數(shù)據(jù)時(shí)經(jīng)常用到的功能。比如,在一個(gè)在線書(shū)店里搜索關(guān)于ASP.NET 的書(shū)的時(shí)候,可能結(jié)果會(huì)是成百上千,而每頁(yè)只列出十條。而且結(jié)果可以根據(jù)title(書(shū)名),price(價(jià)格),page count(頁(yè)數(shù)),author name(作者)等來(lái)排序。我們?cè)诜猪?yè)和排序報(bào)表數(shù)據(jù) 里已經(jīng)討論過(guò), GridView, DetailsView, 和FormView 都有內(nèi)置的分頁(yè)功能,僅僅只需要勾一個(gè)checkbox就可以開(kāi)啟。GridView 還支持內(nèi)置的排序。
不幸的是,DataList 和Repeater 都沒(méi)有提供內(nèi)置的分頁(yè)和排序功能。本章我們將學(xué)習(xí)如何在DataList 和Repeater 里添加分頁(yè)和排序的支持。我們需要?jiǎng)?chuàng)建分頁(yè)界面,顯示正確的頁(yè)的記錄,并在postback過(guò)程中記下瀏覽的頁(yè)。雖然這會(huì)比GridView, DetailsView, 和FormView里花費(fèi)更多的時(shí)間和寫(xiě)更多的代碼,但是也提供了更多的可擴(kuò)展性。
注意:本章集中精力討論分頁(yè),下章我們將學(xué)習(xí)排序。
第一步: 添加分頁(yè)和排序的教程頁(yè)
首先添加本章和下一章需要的頁(yè)。創(chuàng)建一個(gè)名為PagingSortingDataListRepeater的文件夾,然后添加下面的5個(gè)頁(yè),記得全部選擇Site.master。
Default.aspx
Paging.aspx
Sorting.aspx
SortingWithDefaultPaging.aspx
SortingWithCustomPaging.aspx
圖 1: 創(chuàng)建頁(yè)
然后打開(kāi)Default.aspx頁(yè),從UserControls文件夾里拖一個(gè)SectionLevelTutorialListing.ascx用戶控件進(jìn)來(lái)。這個(gè)用戶控件我們已經(jīng)用了很多次了。見(jiàn)母板頁(yè)和站點(diǎn)導(dǎo)航 。
圖 2: 添加用戶控件
為了將排序和分頁(yè)的教程列出來(lái),我們需要將他們添加到site map(站點(diǎn)地圖)里。打開(kāi)Web.sitemap文件,將下面的標(biāo)記語(yǔ)言添加到“Editing and Deleting with the DataList”()的節(jié)點(diǎn)后面:
<siteMapNode url="~/PagingSortingDataListRepeater/Default.aspx" title="Paging and Sorting with the DataList and Repeater" description="Paging and Sorting the Data in the DataList and Repeater Controls"> <siteMapNode url="~/PagingSortingDataListRepeater/Paging.aspx" title="Paging" description="Learn how to page through the data shown in the DataList and Repeater controls." /> <siteMapNode url="~/PagingSortingDataListRepeater/Sorting.aspx" title="Sorting" description="Sort the data displayed in a DataList or Repeater control." /> <siteMapNode url="~/PagingSortingDataListRepeater/SortingWithDefaultPaging.aspx" title="Sorting with Default Paging" description="Create a DataList or Repeater control that is paged using default paging and can be sorted." /> <siteMapNode url="~/PagingSortingDataListRepeater/SortingWithCustomPaging.aspx" title="Sorting with Custom Paging" description="Learn how to sort the data displayed in a DataList or Repeater control that uses custom paging." /> </siteMapNode>
圖 3: 更新 Site Map
回顧一下分頁(yè)
在前面我們學(xué)習(xí)了如何使用GridView, DetailsView, FormView 來(lái)分頁(yè)。這三個(gè)控件都提供了一種稱為默認(rèn)分頁(yè)的功能,僅僅只需要從智能標(biāo)簽里勾上“Enable Paging”(開(kāi)啟分頁(yè))即可。在使用默認(rèn)分頁(yè)時(shí),每次請(qǐng)求數(shù)據(jù) – 無(wú)論是第一頁(yè)還是其它頁(yè)–GridView, DetailsView, 和FormView 都會(huì)重新請(qǐng)求所有的數(shù)據(jù)。然后根據(jù)請(qǐng)求的頁(yè)索引和每頁(yè)顯示的記錄數(shù)來(lái)顯示特定頁(yè)的數(shù)據(jù),而忽略其它數(shù)據(jù)(即雖然被請(qǐng)求但未顯示的數(shù)據(jù))。我們?cè)诜猪?yè)和排序報(bào)表數(shù)據(jù) 里已經(jīng)詳細(xì)的討論過(guò)默認(rèn)分頁(yè)了。
默認(rèn)分頁(yè)由于每次都請(qǐng)求所有的數(shù)據(jù),因此在大數(shù)據(jù)量的情況下并不合適。例如,想象一下每頁(yè)顯示10條數(shù)據(jù),總共有有50,000條。每次用戶瀏覽一頁(yè)時(shí),都要從數(shù)據(jù)庫(kù)請(qǐng)求50,000條數(shù)據(jù),而其中只有10條會(huì)被顯示。
自定義分頁(yè)使用每次只返回請(qǐng)求的數(shù)據(jù),從而解決了默認(rèn)分頁(yè)的性能問(wèn)題。當(dāng)使用自定義分頁(yè)時(shí),我們需要寫(xiě)有效的返回正確的記錄的SQL語(yǔ)句。我們?cè)诶飳W(xué)習(xí)了用SQL Server2005的ROW_NUMBER() keyword 來(lái)創(chuàng)建這樣的語(yǔ)句。
在DataList或Repeater里使用默認(rèn)分頁(yè),我們可以使用PagedDataSource class來(lái)包裝ProductsDataTable里需要分頁(yè)的內(nèi)容。PagedDataSource類有一個(gè)可以賦給任何枚舉類型對(duì)象的DataSource屬性,和PageSize (每頁(yè)顯示的記錄數(shù))and CurrentPageIndex (當(dāng)前頁(yè)的索引)。一旦設(shè)置了這些屬性,PagedDataSource就可以作為任何數(shù)據(jù)控件的數(shù)據(jù)源。PagedDataSource根據(jù)PageSize和CurrentPageIndex來(lái)返回合適的記錄。圖4描述了PagedDataSource類的功能。
圖 4: PagedDataSource使用可分頁(yè)的界面包裝枚舉對(duì)象
PagedDataSource對(duì)象可以在BLL里直接創(chuàng)建和配置,并通過(guò)ObjectDataSource綁定到DataList或Repeater?;蛘咭部梢栽贏SP.NET 頁(yè)的后臺(tái)代碼里直接做這些。如果使用后一種方法,我們就不能使用ObjectDataSource而應(yīng)該直接編程將分頁(yè)數(shù)據(jù)綁定到DataList或Repeater。
PagedDataSource對(duì)象也有支持自定義分頁(yè)的屬性。但是在這里我們將不討論它,因?yàn)槲覀冊(cè)赑roductsBLL類里已經(jīng)有一個(gè)可以精確的返回需要顯示的記錄的方法。本章我們將學(xué)習(xí)如何通過(guò)在ProductsBLL類里添加一個(gè)返回合適的PagedDataSource對(duì)象的方法來(lái)實(shí)現(xiàn)默認(rèn)分頁(yè)。下章我們?cè)儆懻撟远x分頁(yè)。
第二步: 在BLL里添加默認(rèn)的分頁(yè)方法
ProductsBLL類里現(xiàn)在有一個(gè)返回所有product的方法–GetProducts()–和一個(gè)返回特定子集的方法–GetProductsPaged(startRowIndex,maximumRows)。當(dāng)使用默認(rèn)分頁(yè)時(shí),GridView, DetailsView, FormView 使用GetProducts()方法獲取所有的product,但是在內(nèi)部使用PagedDataSource來(lái)顯示正確的記錄子集。在DataList和Repeater里實(shí)現(xiàn)同樣的功能,我們可以在BLL里創(chuàng)建一個(gè)模擬這種行為的方法。
在ProductsBLL里添加一個(gè)帶兩個(gè)整型參數(shù)的方法,名為GetProductsAsPagedDataSource:
pageIndex – 顯示的頁(yè)的索引,從0開(kāi)始
pageSize – 每頁(yè)顯示的記錄數(shù).
GetProductsAsPagedDataSource首先從GetProducts()里獲取所有的記錄。然后創(chuàng)建一個(gè)PagedDataSource對(duì)象,將CurrentPageIndex和PageSize屬性設(shè)置為傳進(jìn)來(lái)的參數(shù),pageIndex和pageSize。方法的最后返回這個(gè)配置過(guò)的PagedDataSource。
[System.ComponentModel.DataObjectMethodAttribute (System.ComponentModel.DataObjectMethodType.Select, false)] public PagedDataSource GetProductsAsPagedDataSource(int pageIndex, int pageSize) { // Get ALL of the products Northwind.ProductsDataTable products = GetProducts(); // Limit the results through a PagedDataSource PagedDataSource pagedData = new PagedDataSource(); pagedData.DataSource = products.Rows; pagedData.AllowPaging = true; pagedData.CurrentPageIndex = pageIndex; pagedData.PageSize = pageSize; return pagedData; }
第三步: 在DataList里使用默認(rèn)分頁(yè)顯示Product
完成GetProductsAsPagedDataSource方法后,我們現(xiàn)在來(lái)創(chuàng)建一個(gè)提供默認(rèn)分頁(yè)的DataList或Repeater。打開(kāi)PagingSortingDataListRepeater文件夾下的Paging.aspx頁(yè),拖一個(gè)DataList進(jìn)來(lái),將ID設(shè)為ProductsDefaultPaging。通過(guò)智能標(biāo)簽創(chuàng)建一個(gè)名為ProductsDefaultPagingDataSource的ObjectDataSource并用GetProductsAsPagedDataSource方法配置它。
圖 5: 創(chuàng)建并配置ObjectDataSource
在UPDATE, INSERT, DELETE 標(biāo)簽的下拉列表里都選擇“(None)”.
圖 6: 在UPDATE, INSERT, DELETE 標(biāo)簽的下拉里選擇“(None)”
因?yàn)镚etProductsAsPagedDataSource方法需要兩個(gè)參數(shù),因此向?qū)?huì)提示我們選擇參數(shù)源。page index和page size的值必須在postback過(guò)程中記下來(lái)。它們可以存在view state,querystring,session里或用其它技術(shù)來(lái)記錄。本章我們使用querystring。
分別使用querystring字段“pageIndex” 和“pageSize”來(lái)配置pageIndex和pageSize。見(jiàn)圖7。由于用戶第一次瀏覽頁(yè)的時(shí)候沒(méi)有querystring,因此還需要設(shè)置這兩個(gè)參數(shù)的默認(rèn)值。將pageIndex的默認(rèn)值設(shè)為0(表示顯示第一頁(yè)數(shù)據(jù)),將pageSize的默認(rèn)值設(shè)為4。
圖 7: 配置參數(shù)
配置完ObjectDataSource后,Visual Studio自動(dòng)為DataList創(chuàng)建一個(gè)ItemTemplate。修改它讓它只顯示product的name,category和supplier。將DataList的RepeatColumns屬性設(shè)為2,Width設(shè)為“100%”, ItemStyle的Width設(shè)為 “50%”. 這樣的設(shè)置會(huì)為兩列提供相同的間距。完成這些后DataList和ObjectDataSource的標(biāo)記語(yǔ)言看起來(lái)應(yīng)該如下:
<asp:DataList ID="ProductsDefaultPaging" runat="server" Width="100%" DataKeyField="ProductID" DataSourceID="ProductsDefaultPagingDataSource" RepeatColumns="2" EnableViewState="False"> <ItemTemplate> <h4><asp:Label ID="ProductNameLabel" runat="server" Text='<%# Eval("ProductName") %>'></asp:Label></h4> Category: <asp:Label ID="CategoryNameLabel" runat="server" Text='<%# Eval("CategoryName") %>'></asp:Label><br /> Supplier: <asp:Label ID="SupplierNameLabel" runat="server" Text='<%# Eval("SupplierName") %>'></asp:Label><br /> <br /> <br /> </ItemTemplate> <ItemStyle Width="50%" /> </asp:DataList> <asp:ObjectDataSource ID="ProductsDefaultPagingDataSource" runat="server" OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL" SelectMethod="GetProductsAsPagedDataSource"> <SelectParameters> <asp:QueryStringParameter DefaultValue="0" Name="pageIndex" QueryStringField="pageIndex" Type="Int32" /> <asp:QueryStringParameter DefaultValue="4" Name="pageSize" QueryStringField="pageSize" Type="Int32" /> </SelectParameters> </asp:ObjectDataSource>
注意:由于這里我們不實(shí)現(xiàn)任何更新或刪除的功能,你可以禁用DataList的view state來(lái)減少頁(yè)面的大小。
第一次瀏覽頁(yè)的時(shí)候,querystring里沒(méi)有提供pageIndex 和pageSize的值,因此將使用默認(rèn)的0和4。見(jiàn)圖8。DataList將顯示4條product記錄。
圖 8: 顯示4條Product
由于還沒(méi)有分頁(yè)的界面,因此用戶現(xiàn)在還不能直接導(dǎo)航到第二頁(yè)。我們將在第四步里創(chuàng)建分頁(yè)界面?,F(xiàn)在我們只能直接在querystring里指定分頁(yè)的參數(shù)來(lái)進(jìn)行分頁(yè)。例如,我們可以將地址從Paging.aspx改為Paging.aspx?pageIndex=2,然后回車,來(lái)瀏覽第二頁(yè)。這樣就可以看到第二頁(yè)的數(shù)據(jù)了,見(jiàn)圖9。
圖 9: 顯示第二頁(yè)數(shù)據(jù)
第四步: 創(chuàng)建分頁(yè)界面
有很多不同的完成分頁(yè)界面的方法。GridView, DetailsView, FormView 提供了4種不同的界面:
Next, Previous(后一頁(yè),前一頁(yè)) – 用戶可以瀏覽上一頁(yè)或下一頁(yè).
Next, Previous, First(第一頁(yè)), Last (最后一頁(yè))– 除了上面的功能,這個(gè)還包含第一頁(yè)和最后一頁(yè)。
Numeric (數(shù)字)–在分頁(yè)界面上列出頁(yè)數(shù),用戶可以隨意的選擇一個(gè)頁(yè) .
Numeric, First, Last – 在上一個(gè)功能的基礎(chǔ)上增加了第一頁(yè)和最后一頁(yè).
對(duì)DataList 和Repeater而言,我們需要決定它的分頁(yè)界面并實(shí)現(xiàn)它。這其中包含了需要?jiǎng)?chuàng)建web控件和當(dāng)特定頁(yè)的button被點(diǎn)時(shí)顯示請(qǐng)求的頁(yè)。另外某些分頁(yè)界面的控件可能需要禁用。例如,當(dāng)使用Next, Previous, First, Last這個(gè)模式來(lái)顯示時(shí),如果瀏覽第一頁(yè)數(shù)據(jù),那么第一頁(yè)和前一頁(yè)的button應(yīng)該被禁用。
本章我們使用 Next, Previous, First, Last界面。添加4個(gè)button,并將ID分別設(shè)為FirstPage,PrevPage,NextPage和LastPage。將Text設(shè)為“<< First”, “< Prev”, “Next >”, “Last >>”.
<asp:Button runat="server" ID="FirstPage" Text="<< First" /> <asp:Button runat="server" ID="PrevPage" Text="< Prev" /> <asp:Button runat="server" ID="NextPage" Text="Next >" /> <asp:Button runat="server" ID="LastPage" Text="Last >>" />
然后為每個(gè)button創(chuàng)建一個(gè)Click事件處理。呆會(huì)我們將添加代碼來(lái)顯示請(qǐng)求的頁(yè)。
記下分頁(yè)的總記錄數(shù)
不管選擇哪種分頁(yè)界面,我們都需要計(jì)算和記下分頁(yè)的總記錄數(shù)??偟男袛?shù)(和page size)來(lái)決定總的頁(yè)數(shù),它決定了那些分頁(yè)界面的控件需要增加或啟用。在我們創(chuàng)建的Next, Previous, First, Last 界面里,page count(頁(yè)數(shù))在兩種情況下需要被用到:
判斷我們是否在瀏覽最后一頁(yè),這種情況下Next 和Last buttons 需要禁用。
如果用戶點(diǎn)了Last button我們需要將它轉(zhuǎn)到最后一頁(yè),它的索引等于page count減1。
page count通過(guò)總行數(shù)除以page size(頁(yè)數(shù))來(lái)計(jì)算得到。例如我們要分頁(yè)79條記錄,每頁(yè)顯示4條,那么page count為20(79/4)。如果我們使用數(shù)字分頁(yè)界面,就可以通過(guò)這個(gè)信息來(lái)決定要顯示多少個(gè)數(shù)字頁(yè)的button。如果分頁(yè)界面只包含Next 和Last buttons,可以通過(guò)page count來(lái)什么時(shí)候禁用Next 和Last buttons。
如果分頁(yè)界面包含Last button(最后一頁(yè)),我們需要在postback過(guò)程中記下分頁(yè)的總記錄數(shù),這樣在點(diǎn)Last button的時(shí)候我們可以獲得最后一頁(yè)的索引。為了方便實(shí)現(xiàn)這個(gè),我們?cè)贏SP.NET頁(yè)的后臺(tái)代碼里創(chuàng)建一個(gè)TotalRowCount屬性來(lái)將這個(gè)值保存到view state里。
private int TotalRowCount { get { object o = ViewState["TotalRowCount"]; if (o == null) return -1; else return (int)o; } set { ViewState["TotalRowCount"] = value; } }
除了TotalRowCount外,還需要為page index,page size和page count創(chuàng)建頁(yè)面級(jí)的只讀屬性來(lái)方便讀取。
private int PageIndex { get { if (!string.IsNullOrEmpty(Request.QueryString["pageIndex"])) return Convert.ToInt32(Request.QueryString["pageIndex"]); else return 0; } } private int PageSize { get { if (!string.IsNullOrEmpty(Request.QueryString["pageSize"])) return Convert.ToInt32(Request.QueryString["pageSize"]); else return 4; } } private int PageCount { get { if (TotalRowCount <= 0 || PageSize <= 0) return 1; else return ((TotalRowCount + PageSize) - 1) / PageSize; } }
獲取分頁(yè)的總記錄數(shù)
從ObjectDataSource的Select()方法返回一個(gè)PagedDataSource對(duì)象包含所有的product記錄,即使只有一部分會(huì)在DataList里顯示。PagedDataSource的Count property 返回將在DataList里顯示的項(xiàng)的數(shù)目。DataSourceCount property 返回PagedDataSource里的所有項(xiàng)的的總數(shù)目。因此我們需要將ASP.NET頁(yè)的TotalRowCount屬性賦值為PagedDataSource的DataSourceCount。
我們?yōu)镺bjectDataSource的Selectd事件創(chuàng)建一個(gè)event handler來(lái)完成這些。在Selectd的event handler里我們獲取ObjectDataSource的Select()方法的返回值–在這種情況下是PagedDataSource。
protected void ProductsDefaultPagingDataSource_Selected (object sender, ObjectDataSourceStatusEventArgs e) { // Reference the PagedDataSource bound to the DataList PagedDataSource pagedData = (PagedDataSource)e.ReturnValue; // Remember the total number of records being paged through // across postbacks TotalRowCount = pagedData.DataSourceCount; }
顯示請(qǐng)求的頁(yè)的數(shù)據(jù)
當(dāng)用戶點(diǎn)分頁(yè)界面上的button時(shí),我們需要顯示請(qǐng)求的頁(yè)的數(shù)據(jù)。由于分頁(yè)的參數(shù)在querystring里指定,因此使用Response.Redirect(url)來(lái)讓用戶重新請(qǐng)求帶合適分頁(yè)參數(shù)的Paging.aspx頁(yè)。例如,顯示第二頁(yè)的數(shù)據(jù),我們將用戶重定向到Paging.aspx?pageIndex=1。
創(chuàng)建一個(gè)RedirectUser(sendUserToPageIndex)方法來(lái)重定向用戶到Paging.aspx?pageIndex=sendUserToPageIndex。然后在四個(gè)按鈕的Click事件處理里調(diào)用這個(gè)方法。在FirstPageClick里調(diào)用RedirectUser(0),在PrevPageClick里調(diào)用RedirectUser(PageIndex-1)。
protected void FirstPage_Click(object sender, EventArgs e) { // Send the user to the first page RedirectUser(0); } protected void PrevPage_Click(object sender, EventArgs e) { // Send the user to the previous page RedirectUser(PageIndex - 1); } protected void NextPage_Click(object sender, EventArgs e) { // Send the user to the next page RedirectUser(PageIndex + 1); } protected void LastPage_Click(object sender, EventArgs e) { // Send the user to the last page RedirectUser(PageCount - 1); } private void RedirectUser(int sendUserToPageIndex) { // Send the user to the requested page Response.Redirect(string.Format("Paging.aspx?pageIndex={0}&pageSize={1}", sendUserToPageIndex, PageSize)); }
完成Click事件處理后,DataList的記錄現(xiàn)在可以通過(guò)button來(lái)分頁(yè)了,你可以測(cè)試一下。
禁用分頁(yè)控件
現(xiàn)在無(wú)論瀏覽哪頁(yè)四個(gè)按鈕都是可用的。然而我們?cè)跒g覽第一頁(yè)時(shí)需要禁用 First 和Previous buttons ,在瀏覽最后一頁(yè)時(shí)需要禁用Next 和Last buttons。通過(guò)ObjectDataSource的Select()方法返回的PagedDataSource對(duì)象有幾個(gè)屬性– IsFirstPage 和 IsLastPage –通過(guò)它們可以判斷用戶瀏覽的是否是第一或最后一頁(yè)數(shù)據(jù)。添加下面的代碼到ObjectDataSource的Selected事件處理里:
// Configure the paging interface based on the data in the PagedDataSource FirstPage.Enabled = !pagedData.IsFirstPage; PrevPage.Enabled = !pagedData.IsFirstPage; NextPage.Enabled = !pagedData.IsLastPage; LastPage.Enabled = !pagedData.IsLastPage;
添加完后,當(dāng)瀏覽第一頁(yè)時(shí),F(xiàn)irst 和Previous buttons 將被禁用。當(dāng)瀏覽最后一頁(yè)時(shí),Next 和 Last buttons 將被禁用。
我們最后來(lái)實(shí)現(xiàn)在分頁(yè)界面里通知用戶他們當(dāng)前是瀏覽的哪頁(yè)和一共有多少頁(yè)。添加一個(gè)Label控件并將ID設(shè)為CurrentPageNumber。在ObjectDataSource的Selected事件處理中設(shè)置它的Text屬性,讓它顯示當(dāng)前瀏覽的頁(yè)(PageIndex+1)和總頁(yè)數(shù)(PageCount)。
// Display the current page being viewed... CurrentPageNumber.Text = string.Format("You are viewing page {0} of {1}...", PageIndex + 1, PageCount);
圖10是第一次瀏覽Paging.aspx頁(yè)的樣子。由于querystring是空的,因此DataList默認(rèn)顯示最開(kāi)始的4條product。First 和Previous buttons 被禁用。點(diǎn)Next 會(huì)顯示下面的4條記錄(見(jiàn)圖11),而First 和Previous buttons 同時(shí)被啟用了。
圖 10: 第一頁(yè)數(shù)據(jù)
圖 11: 第二頁(yè)數(shù)據(jù)
注意:分頁(yè)界面可以進(jìn)一步改善,比如增加允許用戶來(lái)指定每頁(yè)顯示多少記錄。例如添加一個(gè)DropDownList列出page size的選項(xiàng),比如5, 10, 25, 50, 和ALL。用戶選擇了page size后會(huì)重定向到Paging.aspx?pageIndex=0&pageSize=selectedPageSize。我將這個(gè)作為練習(xí)留給讀者自己完成。
使用自定義分頁(yè)
DataList使用沒(méi)有效率的默認(rèn)分頁(yè)技術(shù)。當(dāng)大數(shù)據(jù)量時(shí),我們需要使用自定義分頁(yè)。雖然實(shí)現(xiàn)的細(xì)節(jié)有所不同,但是分頁(yè)里的概念和默認(rèn)分頁(yè)是一樣的。默認(rèn)分頁(yè)時(shí),使用ProductsBLL類的GetProductsPaged方法(而不是GetProductsAsPagedDataSource)。正如在大數(shù)據(jù)量時(shí)提高分頁(yè)的效率 里討論的那樣,GetProductsPaged需要傳入開(kāi)始行的索引和行的最大數(shù)目。這些參數(shù)可以通過(guò)默認(rèn)分頁(yè)里使用的querystring里的pageIndex和pageSize參數(shù)來(lái)保存。
由于自定義分頁(yè)里沒(méi)有PagedDataSource,所以需要其它技術(shù)來(lái)決定總記錄數(shù)和判斷我們是否顯示第一或最后一頁(yè)數(shù)據(jù)。ProductsBLL類的TotalNumberOfProducts()方法返回roduct的總記錄數(shù)。而為了判斷是否瀏覽的是第一頁(yè)數(shù)據(jù),我們需要檢查開(kāi)始行的索引–如果是0,則表示在瀏覽第一頁(yè)。如果開(kāi)始行的索引加上最大的行數(shù)大于或等于總記錄數(shù)則表示在最后一頁(yè).我們將在下章詳細(xì)的討論如何實(shí)現(xiàn)自定義分頁(yè)。
總結(jié)
DataList和Repeater都沒(méi)有提供象GridView, DetailsView, FormView 那樣的分頁(yè)的支持,這樣的功能需要我們來(lái)實(shí)現(xiàn)。最簡(jiǎn)單的實(shí)現(xiàn)方法是使用默認(rèn)分頁(yè),將所有的product都包裝到PagedDataSource里,然后綁定PagedDataSource到DataList或Repeater。本章我們?cè)赑roductsBLL類里添加GetProductsAsPagedDataSource方法,它返回PagedDataSource。ProductsBLL類已經(jīng)包含了自定義分頁(yè)需要的方法– GetProductsPaged和TotalNumberOfProducts。
不管是自定義方法里獲取精確的記錄還是默認(rèn)方法里獲取所有記錄,我們都需要手動(dòng)添加分頁(yè)界面。本章我們創(chuàng)建的是包含4個(gè)button控件的Next, Previous, First, Last interface 。當(dāng)然還添加了一個(gè)顯示當(dāng)前頁(yè)和總頁(yè)數(shù)的Label控件。
下章將學(xué)習(xí)如何為DataList和Repeater提供排序功能。我們也會(huì)創(chuàng)建一個(gè)既支持分頁(yè)又支持排序的DataList(和使用默認(rèn)和自定義分頁(yè)的例子)
祝編程快樂(lè)!
作者簡(jiǎn)介
本系列教程作者 Scott Mitchell,著有六本ASP/ASP.NET方面的書(shū),是4GuysFromRolla.com的創(chuàng)始人,自1998年以來(lái)一直應(yīng)用 微軟Web技術(shù)。大家可以點(diǎn)擊查看全部教程《[翻譯]Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程》,希望對(duì)大家的學(xué)習(xí)ASP.NET有所幫助。
- .NET實(shí)現(xiàn)Repeater控件+AspNetPager控件分頁(yè)
- asp.net Repeater分頁(yè)實(shí)例(PageDataSource的使用)
- asp.net中使用repeater和PageDataSource搭配實(shí)現(xiàn)分頁(yè)代碼
- asp.net中讓Repeater和GridView支持DataPager分頁(yè)
- asp.net下Repeater使用 AspNetPager分頁(yè)控件
- asp.net Repeater之非常好的數(shù)據(jù)分頁(yè)
- asp.net repeater手寫(xiě)分頁(yè)實(shí)例代碼
- ASP.NET程序中用Repeater實(shí)現(xiàn)分頁(yè)
- .NET中的repeater簡(jiǎn)介及分頁(yè)效果
相關(guān)文章
無(wú)法在Web服務(wù)器上啟動(dòng)調(diào)試。未將項(xiàng)目配置為進(jìn)行調(diào)試
無(wú)法在Web服務(wù)器上啟動(dòng)調(diào)試。未將項(xiàng)目配置為進(jìn)行調(diào)試...2006-10-10在ASP.NET 2.0中操作數(shù)據(jù)之六十五:在TableAdapters中創(chuàng)建新的存儲(chǔ)過(guò)程
本文主要講解使用TableAdapter設(shè)置向?qū)ё詣?dòng)創(chuàng)建增刪改查的存儲(chǔ)過(guò)程,雖然自動(dòng)創(chuàng)建存儲(chǔ)過(guò)程可以節(jié)省時(shí)間,但他們會(huì)包含一些無(wú)用的參數(shù),下節(jié)我們會(huì)介紹TableAdapter使用現(xiàn)有的存儲(chǔ)過(guò)程。2016-05-05我今天開(kāi)始正式學(xué)習(xí).net遇到的問(wèn)題
我今天開(kāi)始正式學(xué)習(xí).net遇到的問(wèn)題...2006-10-10在ASP.NET 2.0中操作數(shù)據(jù)之五十一:從GridView的頁(yè)腳插入新記錄
本文介紹在ASP.NET 2.0中如何在GridView的頁(yè)腳動(dòng)態(tài)插入一行新記錄,要顯示頁(yè)腳行只需要設(shè)置ShowFooter屬性為true。我們可以這樣對(duì)頁(yè)腳行進(jìn)行用戶定制:將每一列轉(zhuǎn)換成TemplateField,并在其FooterTemplate模板定制插入界面。2016-05-05.NET?Core、Xamarin、.NET?Standard和.NET?Framework四者之間的區(qū)別介紹
這篇文章介紹了.NET?Core、Xamarin、.NET?Standard和.NET?Framework四者之間的區(qū)別,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-01-01在ASP.NET 2.0中操作數(shù)據(jù)之五十二:使用FileUpload上傳文件
本文主要介紹ASP.NET中為了演示上傳文件,我們?cè)跀?shù)據(jù)庫(kù)上建了兩個(gè)字段,分別存儲(chǔ)二進(jìn)制圖片和PDF路徑,然后介紹了如何使用FileUpload 完成上傳文件。2016-05-05Microsoft .Net Remoting系列教程之三:Remoting事件處理全接觸
本文主要講解.Net Remoting中的Remoting事件處理,需要的朋友可以參考下。2016-05-05