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

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