本文英文原版及代碼下載:
http://aspnet.4guysfromrolla.com/articles/021308-1.aspx
利用ListView和DataPager控件來對數據分頁
導言:
GridView, DetailsView,FormView控件等都支持分頁功能. 當配置為支持分頁時,這些控件都呈現為包含LinkButtons, Buttons,或ImageButtons的分頁界面.我們通過設置相關的屬性來定制分頁界面,比如使用Next/Previous,數字分頁等.雖然這些配置都很好,但實現用戶自定義的余地很小.比如,配置選項允許你指定分頁接口出現在控件的頂部或者底部(或上下都出現),但是如果你希望分頁接口出現在頁面的其它地方,與控件分離,那就沒辦法了.
為此,ASP.NET開發團隊用ListView控件來解決,將該控件的分頁支持剝離出來,用另一個控件DataPager來實現.DataPager控件的唯一目的就是呈現一個分頁接口,并與相應的ListView控件關聯起來.ListView 和 DataPager的這種剝離關系,可以允許進行更大程度的分頁界面定制.
Paging Basics
DataPager控件使用如下3方面的信息來進行分頁:
PagedControlID -與DataPager相關的ListView的ID值
StartRowIndex -當前頁面要顯示的記錄的第一條記錄的index索引值
MaximumRows - 每頁最多顯示的記錄數
比如,要顯示第一頁的記錄,且每頁顯示10條記錄.那么StartRowIndex 和 MaximumRows的值就應分別為0 和 10,如果是第二頁的記錄,則為10 和 10. 第三頁的為20 和 10.另外還有一個只讀的TotalRowCount屬性, 用于返回總記錄條數.
DataPager包含一系列的DataPagerFields,每個DataPagerField展示一種分頁接口. 在.NET Framework 3.5里有3個DataPagerFields: NextPreviousPagerField, NumericPagerField, 以及TemplatePagerField.其中,NextPreviousPagerField展示的是First/Previous/Next/Last按鈕;而NumericPagerField展示的是page numbers;TemplatePagerField則是通過模板來創建分頁接口,不過我們要自己創建該模板.
當用戶使用該分頁接口時,比如點擊"Next"按鈕時,接著產生頁面回傳,DataPagerField意識到這是由分頁接口上的某個元素引起的. DataPagerField 就確定好StartRowIndex 和 MaximumRows的值,并傳給DataPager類的SetPageProperties方法. 接著,DataPager調用其對應的ListView控件的SetPageProperties方法,該方法將促使ListView重新綁定數據,并展示我們期望的記錄.
默認分頁VS自定義分頁
ListView 和 DataPager控件提供了2種分頁模式:默認分頁和自定義分頁.這2種方式在性能和配置、使用等易操作性方面做出一種權衡.SqlDataSource控件使用的是默認分頁、ObjectDataSource默認使用默認分頁,不過它也可以通過一個很方便的機制來實現自定義分頁.務必謹記的是,ListView僅僅是展示數據,從數據庫檢索數據實際上是它的數據源控件來完成的.
默認分頁時,每次顯示一頁新數據時,都會檢索所有的記錄。一旦返回所有的記錄后,ListView再基于StartRowIndex 和 MaximumRows值從所有記錄中挑選出所需的記錄.
自定義分頁時,我們要多做一點工作.我們要配置數據源控件僅僅檢索某個頁面所需要的那些記錄,而不是盲目地檢索所有的記錄.
關于默認分頁和自定義分頁,以及在性能和易操作性如何權衡的問題,請參閱文章《 Custom Paging in ASP.NET with SQL Server 2005》.
創建DataPager及定義其DataPagerFields
用ListView 和 DataPager控件貫徹分頁雖不像點選一個checkbox那么簡單,但也不會太困難.本文下載代碼里包含2個DataPager案例,它們都基于《Displaying Data with the ListView》那篇文章里的SimpleListView.aspx,我們接下來將探討.
首先,添加并配置ListView控件,使其按我們期望的格式顯示數據.然后,添加一個或多個DataPager控件到頁面,任意你期望的地方.DataPager可以放在ListView控件的LayoutTemplate模板,或頁面上ListView控件之外的任何地方.
添加完DataPager后,在Visual Studio設計視圖里它看起來是一個灰色的box.要定制DataPagerFields,點擊DataPager智能標簽里的"Edit Pager Fields"鏈接.這將打開Fields對話框(如下圖).在這里,我們可以指定添加何種DataPagerFields,設置其相關屬性.在這里我添加NextPreviousPagerField,并將ButtonType屬性設置為Button(這樣,它將在分頁接口里呈現Button控件,而不是默認的LinkButtons控件),同時我將ShowFirstPageButton 和 ShowLastPageButton屬性設置為True.這樣它們就和Next 和Previous按鈕一起出現在分頁接口上.
圖1
點擊OK關閉Fields對話框后,DataPager的聲明代碼里就包含了DataPagerField信息,此外,在設計器里分頁接口呈現為First/Previous/Next/Last按鈕.
在測試頁面之前,我們還要設置2個屬性.首先將DataPager的PagedControlID屬性設置為頁面上相關的ListView的ID值.然后,設置DataPager的PageSize屬性,指定相關聯的 ListView每頁展示記錄的條數 (默認值為10).完成設置后,代碼應和下面的類似:
<asp:DataPager ID="ProductListPagerSimple" runat="server"
PagedControlID="ProductList" PageSize="5">
<Fields>
<asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True"
ShowLastPageButton="True" />
</Fields>
</asp:DataPager>
完成后在瀏覽器里測試,如下面的截屏所示,ListView控件每頁只顯示了5條記錄(因為我將DataPager的PageSize屬性設置為5),此外First 和 Previous按鈕不可用,因為我們查看的是第一頁的數據.
圖2
上面截屏里的分頁接口位于ListView的頂部,但務必牢記:一個ListView可用有多個DataPager控件.我們可以在ListView的底部再增加一個DataPager,將其PagedControlID 和 PageSize屬性像上面那個DataPager一樣進行設置.
在DataPager里指定多個DataPagerFields
前面的例子我們在DataPager里只使用了一個DataPagerField(也就是一個NextPreviousPagerField),不過我們可以在DataPager里使用多個DataPagerField.這種靈活性可以允許我們創建混合分頁接口,比如包含numeric pages和First and Last buttons的分頁接口.
為創建這樣的一個接口,向頁面添加一個DataPager,并設置好其PagedControlID 和 PageSize屬性.然后打開Fields對話框,并添加3個DataPagerFields:一個NextPreviousPagerField,緊接著是一個NumericPagerField,最后一個還是NextPreviousPagerField.設置第一個NextPreviousPagerField的屬性,使其只顯示First按鈕,同樣的,設置最后那個NextPreviousPagerField,使其只顯示Last按鈕.放心大膽的隨意設置First 和 Last按鈕顯示的文本——我將First按鈕設置為<<,而將Last按鈕的文本設置為>>,如下:
<asp:DataPager ID="ProductListPagerCombo" runat="server"
PagedControlID="ProductList" PageSize="5">
<Fields>
<asp:NextPreviousPagerField FirstPageText="<<" ShowFirstPageButton="True"
ShowNextPageButton="False" ShowPreviousPageButton="False" />
<asp:NumericPagerField />
<asp:NextPreviousPagerField LastPageText=">>" ShowLastPageButton="True"
ShowNextPageButton="False" ShowPreviousPageButton="False" />
</Fields>
</asp:DataPager>
最終結果是一個混合分頁接口,如下圖所示.注意頁面上有2個DataPagers.頂部的為First/Previous/Next/Last形式的接口,而底部的為混合接口.
圖3
用TemplatedPagerField創建一個用戶定制分頁接口
如果NumericPagerField 和 NextPreviousPagerField都不能滿足你的分頁接口要求,你可以利用TemplatedPagerField來創建你自定義的分頁接口.使用它,你,作為一個page developer,就要自己來創建分頁接口、探測用戶什么時候點擊了分頁接口,并更新DataPager 和 ListView作為回應.
我們創建一個分頁接口,它枚舉所有的pages,而這些pages是一個DropDownList控件的ListItems,它允許用戶在下拉列表里選擇某個頁面,直接跳到那個頁面.為此,向頁面添加一個DataPager控件,設置其使用TemplatedPagerField,我們可以直接在聲明代碼里實現,也可以在DataPager的智能標簽里通過“Edit Templates”選項來實現.不管以哪種方式,向模板里添加一個DropDownList控件,設置其ID為PageJump,并將AutoPostBack屬性設置為True.
接下來我們要將這些pages對DropDownList控件賦值.由于每次ListView綁定到數據源時都會發生,因此我們為ListView控件的DataBound事件創建一個事件處理器,添加如下的代碼:
Protected Sub ProductList_DataBound(ByVal sender As Object, ByVal e As System.EventArgs) Handles ProductList.DataBound
Dim currentPage As Integer = (DataPagerID.StartRowIndex / DataPagerID.PageSize) + 1
Dim totalPages As Integer = DataPagerID.TotalRowCount / DataPagerID.PageSize
'Populate the DropDownList if needed
Dim ddl As DropDownList = CType(DataPagerID.Controls(0).FindControl("PageJump"), DropDownList)
If ddl.Items.Count = 0 Then
'Add a list item for each page
For i As Integer = 1 To totalPages
ddl.Items.Add(i.ToString())
Next
'Set the DDL to the appropriate page value
ddl.Items.FindByValue(currentPage.ToString()).Selected = True
End If
End Sub
代碼首先處理當前要訪問的頁面,以及總頁數.這都要用到DataPager控件的 StartRowIndex, PageSize,以及TotalRowCount屬性.
然后編程引用id為PageJump的DropDownList控件.注意,為了引用TemplatePagerField里的控件,我們使用了稍微復雜點的代碼:DataPagerID.Controls(0).FindControl("controlID").
遍歷page numbers(從1到totalPages),為每一頁添加一個ListItem.最后將當前頁面對應的DropDownList item選中.
如果你現在登錄該頁面,你將看到在DataPager里包含了一個DropDownList控件,它的下拉列表里包含了所有的頁面.此外,如果在下拉列表里選擇另一個頁面將觸發頁面回傳,但顯示的數據記錄卻并沒有發生改變,這是因為我們還沒有處理DropDownList控件的SelectedIndexChanged event事件——在該事件里我們需要調用DataPager的SetPageProperties方法,傳入新的StartRowIndex 和 MaximumRows的值,這樣才能更新ListView控件里展示的數據記錄.
要給模板里的一個控件創建一個事務處理器,需要在在該控件的聲明代碼里添加OnEventName=EventHandler的語法構造.我們可以通過手動輸入也可以在雙擊該DropDownList控件來實現.不管用哪種方式,創建好該事件處理器后添加如下的代碼:
Protected Sub PageJump_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Dim PageJumpDDL As DropDownList = CType(sender, DropDownList)
Dim pageNo As Integer = Convert.ToInt32(PageJumpDDL.SelectedValue)
Dim startRowIndex As Integer = (pageNo - 1) * ProductListPager.PageSize
DataPagerID.SetPageProperties(startRowIndex, DataPagerID.PageSize, True)
End Sub
上述代碼首先編程引用該id為PageJump 的DropDownList控件,以得到其SelectedValue值。被請求的page number用于計算StartRowIndex值,再將該值連同DataPager控件的PageSize值一起傳遞給DataPager的 SetPageProperties方法.
最終結果是DropDownList列出了所有的page number,當選擇某頁時將觸發頁面回傳,并將該頁的數據顯示出來.
圖4
結語:
與以前的控件不同,ListView并沒有直接的支持分頁,相反其分頁接口由另一個Web control——DataPager來實現.而DataPager的界面又由其DataPagerFields來呈現..NET Framework有3個內置的DataPagerFields:也即NextPreviousPagerField, NumericPagerField,以及 TemplatePagerField.在本文我們探討了如何使用這3種fields.
祝編程愉快!
ASP.NET 3.5's ListView and DataPager—Part4:利用ListView和DataPager控件來對數據分頁
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
