導(dǎo)言
分頁(yè)和排序是在WEB應(yīng)用程序中展現(xiàn)數(shù)據(jù)常見(jiàn)的功能。比如,當(dāng)我們?cè)谝粋€(gè)網(wǎng)上書店搜索ASP.NET書籍的時(shí)候,可能有幾百本相關(guān)書籍,但是我們只希望每頁(yè)顯示10條有效記錄。而且,我們還希望結(jié)果能根據(jù)標(biāo)題、價(jià)格、頁(yè)數(shù)和作者等等來(lái)進(jìn)行排序。過(guò)去的23個(gè)教程中我們研究了如何建立各種報(bào)表,包括在界面上添加編輯和刪除數(shù)據(jù)。但是我們沒(méi)有研究如何對(duì)數(shù)據(jù)進(jìn)行排序,對(duì)于分頁(yè)我們也僅在研究DetailsView和FormView控件的時(shí)候看到。
Step 1:添加分頁(yè)和排序頁(yè)面
在我們開(kāi)始以前,首先讓我們花些時(shí)間來(lái)添加包括本篇在內(nèi)的最近四篇教程需要用到的頁(yè)面。我們先在項(xiàng)目中新建一個(gè)稱作PagingAndSorting的文件夾,接下來(lái),為目錄新增以下幾個(gè)頁(yè)面,并配置為使用Site.master母板頁(yè)。
Default.aspx
SimplePagingSorting.aspx
EfficientPaging.aspx
SortParameter.aspx
CustomSortingUI.aspx
圖1:創(chuàng)建一個(gè)PagingAndSorting文件夾并且添加教程的頁(yè)面
下一步,讓我們打開(kāi)Default.aspx頁(yè)面并且從UserControls中拖拽SectionLevelTutorialListing.ascx用戶控件到設(shè)計(jì)界面。我們?cè)谀赴屙?yè)和站點(diǎn)導(dǎo)航教程中創(chuàng)建的這個(gè)用戶控件遍歷站點(diǎn)地圖并且以符號(hào)列表形式把它們呈現(xiàn)出來(lái)。
圖2:把SectionLevelTutorialListing.ascx用戶控件加入Default.aspx
要讓顯示我們將要?jiǎng)?chuàng)建的分頁(yè)和排序教程,我們需要把他們加入站點(diǎn)地圖中。打開(kāi)Web.sitemap文件并且把下列代碼加在“編輯、插入和刪除”siteMapNode標(biāo)記之后:
siteMapNode title="Paging and Sorting" url="~/PagingAndSorting/Default.aspx"
description="Samples of Reports that Provide Paging and Sorting Capabilities">
siteMapNode url="~/PagingAndSorting/SimplePagingSorting.aspx"
title="Simple Paging Sorting Examples"
description="Examines how to add simple paging and sorting support." />
siteMapNode url="~/PagingAndSorting/EfficientPaging.aspx"
title="Efficiently Paging Through Large Result Sets"
description="Learn how to efficiently page through large result sets." />
siteMapNode url="~/PagingAndSorting/SortParameter.aspx"
title="Sorting Data at the BLL or DAL"
description="Illustrates how to perform sorting logic in the Business Logic
Layer or Data Access Layer." />
siteMapNode url="~/PagingAndSorting/CustomSortingUI.aspx"
title="Customizing the Sorting User Interface"
description="Learn how to customize and improve the sorting user interface." />
/siteMapNode>
圖3:更新站點(diǎn)地圖使之包含新的頁(yè)面
Step 2:在GridView中顯示產(chǎn)品信息
在我們真正實(shí)現(xiàn)分頁(yè)和排序功能以前,讓我們首先創(chuàng)建一個(gè)標(biāo)準(zhǔn)的,沒(méi)有排序和分頁(yè)功能的GridView來(lái)顯示產(chǎn)品信息。其實(shí)這個(gè)工作我們已經(jīng)做過(guò)很多次了,大家也應(yīng)該很熟悉了。首先打開(kāi)SimplePagingSorting.aspx頁(yè)面并且從工具箱中拖一個(gè)GridView控件到設(shè)計(jì)器,配置它的ID屬性為Products。接著,新建一個(gè)ObjectDataSource并使用ProductsBLL類的GetProducts()方法來(lái)獲取所有的產(chǎn)品信息。
圖4:使用GetProducts()方法獲取所有產(chǎn)品信息
因?yàn)檫@個(gè)報(bào)表是只讀的,我們不需要把ObjectDataSource的Insert(), Update(), 和 Delete()方法映射到相應(yīng)的ProductsBLL方法,因此,對(duì)于UPDATE, INSERT, 和 DELETE頁(yè)我們從下拉列表中選取(None)。
圖5:對(duì)于UPDATE, INSERT, 和DELETE頁(yè),我們從下拉列表中選擇(None)選項(xiàng)
下一步,讓我們調(diào)整GridView的字段使之只顯示產(chǎn)品名、供應(yīng)商、分類、價(jià)格和狀態(tài)。另外,我們可以盡管進(jìn)行一些格式上的調(diào)整,比如配置價(jià)格的HeaderText以符合我們的貨幣形式。經(jīng)過(guò)這些修改之后,我們的GridView代碼應(yīng)該和下面的差不多:
asp:GridView ID="Products" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1"
EnableViewState="False">
Columns>
asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
asp:BoundField DataField="SupplierName" HeaderText="Supplier"
ReadOnly="True" SortExpression="SupplierName" />
asp:BoundField DataField="UnitPrice" HeaderText="Price"
SortExpression="UnitPrice" DataFormatString="{0:C}"
HtmlEncode="False" />
asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
SortExpression="Discontinued" />
/Columns>
/asp:GridView>
圖6顯示了在瀏覽器中的效果,但是注意到,我們?cè)谝粋€(gè)屏幕上顯示產(chǎn)品。顯示了每個(gè)產(chǎn)品的名字、分類、供應(yīng)商、價(jià)格和狀態(tài)。
圖6:每個(gè)產(chǎn)品都列出來(lái)了
Step 3:添加分頁(yè)支持
在一個(gè)屏幕上列出所有的產(chǎn)品對(duì)于用戶查看數(shù)據(jù)非常不方便。要讓結(jié)果更加可以管理,我們應(yīng)該把數(shù)據(jù)分幾個(gè)頁(yè)面來(lái)呈現(xiàn),并提供用戶切換頁(yè)面的功能。要實(shí)現(xiàn)這個(gè)只需要選擇GridView智能標(biāo)簽前的Paging復(fù)選框即可(其實(shí)就是把AllowPaging屬性設(shè)置為true)。
圖7:點(diǎn)擊Enable Paging復(fù)選框來(lái)支持分頁(yè)
開(kāi)啟分頁(yè)以后就能限制每頁(yè)顯示的記錄數(shù)量并且在GridView中增加了分頁(yè)導(dǎo)航。默認(rèn)如圖7,是一系列頁(yè)面的數(shù)字,運(yùn)行用戶快速?gòu)囊粋€(gè)頁(yè)面切換到另一個(gè)。其實(shí)我們并不陌生,在為過(guò)去的教程中我們已經(jīng)為DetailsView個(gè)FormView控件提供過(guò)分頁(yè)支持。
DetailsView和FormView控件僅僅支持每一頁(yè)顯示一條記錄。但是對(duì)于GridView,有一個(gè)PageSize 屬性,能讓我們配置每頁(yè)顯示的記錄數(shù)(默認(rèn)是設(shè)置為10)。
GridView, DetailsView 和 FormView分頁(yè)導(dǎo)航能使用下面的屬性來(lái)配置:
PagerStyle –指示分頁(yè)導(dǎo)航的樣式,能設(shè)置BackColor, ForeColor, CssClass, HorizontalAlign等等。
PagerSettings –包含大量屬性來(lái)自定義分頁(yè)導(dǎo)航的功能;PageButtonCount代表顯示在底部分頁(yè)導(dǎo)航的最大頁(yè)面數(shù)(默認(rèn)為10);Mode 屬性 代表分頁(yè)操作的形式,能設(shè)置為:
NextPrevious –顯示下一頁(yè)和上一頁(yè)按鈕,讓用戶一次朝后或者朝前翻一頁(yè)
NextPreviousFirstLast –除了下一頁(yè)和上一頁(yè)按鈕外,還提供第一頁(yè)和最后一頁(yè)按鈕,能讓用戶快速定位到首頁(yè)或者末頁(yè)數(shù)據(jù)
Numeric –顯示一系列頁(yè)面數(shù)字,讓用戶直接點(diǎn)擊數(shù)字切換到相應(yīng)頁(yè)面
NumericFirstLast –除了頁(yè)面數(shù)字以外還提供第一頁(yè)和最后一頁(yè)按鈕,讓用戶能快速定位到首頁(yè)或者末頁(yè)數(shù)據(jù),只有當(dāng)沒(méi)有顯示首頁(yè)或者末頁(yè)數(shù)字時(shí)才顯示按鈕
此外,GridView, DetailsView和 FormView還提供了PageIndex 和 PageCount屬性來(lái)指示當(dāng)前呈現(xiàn)的頁(yè)面和頁(yè)面總數(shù)。PageIndex屬性從0開(kāi)始編號(hào),因此我們?yōu)g覽第一頁(yè)的時(shí)候就為0,而PageCount是從1開(kāi)始編號(hào)的,因此PageIndex的范圍在0和PageCount – 1之間。
讓我們?cè)倩ㄒ恍r(shí)間來(lái)改進(jìn)GridView分頁(yè)導(dǎo)航的默認(rèn)外觀。首先,我們把分頁(yè)導(dǎo)航居右并且設(shè)置為灰色背景色。我們不希望直接設(shè)置GridView的PagerStyle屬性來(lái)實(shí)現(xiàn),而是在Styles.css中創(chuàng)建一個(gè)稱作PagerRowStyle 的CSS類,然后設(shè)置主題文件中PagerStyle的CssClass屬性進(jìn)行關(guān)聯(lián)。首先打開(kāi)Styles.css然后把下面CSS類定義加入文件:
.PagerRowStyle
{
background-color: #ddd;
text-align: right;
}
接著,打開(kāi)App_Themes 文件夾中DataWebControls 文件夾下的GridView.skin文件。我們?cè)谀赴屙?yè)和站點(diǎn)導(dǎo)航教程中提到過(guò),Skin文件能為WEB控件指定一個(gè)默認(rèn)的屬性值。因此,我們?cè)O(shè)置PagerStyle的CssClass屬性為PagerRowStyle。同樣,讓我們配置分頁(yè)導(dǎo)航來(lái)顯示5個(gè)頁(yè)面數(shù)字(NumericFirstLast模式)。
asp:GridView runat="server" CssClass="DataWebControlStyle">
AlternatingRowStyle CssClass="AlternatingRowStyle" />
RowStyle CssClass="RowStyle" />
HeaderStyle CssClass="HeaderStyle" />
FooterStyle CssClass="FooterStyle" />
SelectedRowStyle CssClass="SelectedRowStyle" />
PagerStyle CssClass="PagerRowStyle" />
PagerSettings Mode="NumericFirstLast" PageButtonCount="5" />
/asp:GridView>
分頁(yè)用戶體驗(yàn)
我們?yōu)镚ridView啟用了分頁(yè)又在GridView.skin文件中配置了PagerStyle和PagerSettings,圖8顯示了瀏覽器中的呈現(xiàn)。注意到,每頁(yè)只有10條記錄,從分頁(yè)導(dǎo)航上我們可以知道現(xiàn)在瀏覽的是第一頁(yè)的數(shù)據(jù)。
圖8:?jiǎn)⒂梅猪?yè)后每次只顯示一部分記錄
當(dāng)用戶點(diǎn)擊分頁(yè)導(dǎo)航中某一個(gè)頁(yè)面數(shù)字,頁(yè)面回發(fā)并且呈現(xiàn)所請(qǐng)求的頁(yè)面的數(shù)據(jù)。圖9顯示了點(diǎn)擊最后一頁(yè)的效果。注意到,最后一頁(yè)只有一條記錄,因?yàn)榭偣灿?1條記錄,每頁(yè)顯示10條記錄,8頁(yè)80條,最后一頁(yè)就剩下一條了。
圖9:點(diǎn)擊一個(gè)頁(yè)面數(shù)字頁(yè)面回發(fā)顯示相應(yīng)的一組記錄
分頁(yè)服務(wù)端工作方式
當(dāng)用戶點(diǎn)擊了分頁(yè)導(dǎo)航中的按鈕后,頁(yè)面回發(fā)并開(kāi)始下面服務(wù)端工作流:
1.GridView(或者 DetailsView 或者 FormView) PageIndexChanging時(shí)間觸發(fā)
2.ObjectDataSource從BLL獲取所有數(shù)據(jù);GridView的PageIndex和PageSize屬性用來(lái)檢測(cè)哪些從BLL獲取的數(shù)據(jù)需要顯示在頁(yè)面上
3.GridView的PageIndexChanged事件觸發(fā)
在第二步中,ObjectDataSource從數(shù)據(jù)源獲取所有數(shù)據(jù)。如果我們僅僅是把AllowPaging屬性設(shè)置為true來(lái)進(jìn)行分頁(yè)的話,默認(rèn)方式分頁(yè)的WEB控件就會(huì)獲取所有數(shù)據(jù)并從中挑選合適的以HTML呈現(xiàn)在瀏覽器上。出為數(shù)據(jù)庫(kù)中的數(shù)據(jù)被BLL或者ObjectDataSource進(jìn)行緩存,否則對(duì)于大數(shù)據(jù)量的系統(tǒng)或者大并發(fā)的應(yīng)用程序來(lái)說(shuō)這種工作方式是非常低效的。
在下一個(gè)教程中,我們將會(huì)研究如何實(shí)現(xiàn)自定義分頁(yè)。使用自定義分頁(yè)我們就能指示ObjectDataSource精確地獲取用戶請(qǐng)求的那些數(shù)據(jù)。你能想象到,對(duì)于大數(shù)據(jù)的記錄集,自定義分頁(yè)能極大增加效率。
注意:默認(rèn)的分頁(yè)方式不適合大數(shù)據(jù)集合系統(tǒng)和大流量的多并發(fā)情況,自定義分頁(yè)能改善但是它確實(shí)需要很多修改來(lái)實(shí)現(xiàn)(而不是象默認(rèn)分頁(yè)方式那樣僅僅選擇一個(gè)復(fù)選框)。因此,默認(rèn)的分頁(yè)方式對(duì)于小型的,小流量的網(wǎng)站來(lái)說(shuō)比較合適的,因?yàn)樗膶?shí)現(xiàn)確實(shí)非常簡(jiǎn)單和快速。
例如,如果我們確信數(shù)據(jù)庫(kù)內(nèi)不會(huì)多余100個(gè)產(chǎn)品。如果我們使用自定義分頁(yè)的話,多花的那些時(shí)間和贏得的效率來(lái)說(shuō)是不值得的。然而,如果我那把有幾千幾萬(wàn)的產(chǎn)品的話,不實(shí)現(xiàn)自定義分頁(yè)的話就會(huì)極大地降低我們應(yīng)用程序的性能。
Step 4:自定義分頁(yè)體驗(yàn)
數(shù)據(jù)Web控件提供了一些屬性來(lái)增進(jìn)分頁(yè)體驗(yàn)。例如,PageCount屬性指示總共有多少頁(yè)面,PageIndex屬性指示當(dāng)前訪問(wèn)的頁(yè)面,并能通過(guò)設(shè)置它來(lái)快速定位到某一頁(yè)。為了演示如何使用這些屬性來(lái)增進(jìn)用戶分頁(yè)體驗(yàn),讓我們?cè)陧?yè)面上添加一個(gè)Label Web控件來(lái)顯示用戶當(dāng)前訪問(wèn)的頁(yè)面,添加一個(gè)DropDownList控件來(lái)讓用戶快速切換到某個(gè)頁(yè)面。
首先,在頁(yè)面上添加一個(gè)Label Web控件,設(shè)置它的ID屬性為PagingInformation,然后把Text清空。接著,為GridView的DataBound事件創(chuàng)建一個(gè)事件處理器,然后添加如下代碼:
protected void Products_DataBound(object sender, EventArgs e)
{
PagingInformation.Text = string.Format("You are viewing page {0} of {1}...",
Products.PageIndex + 1, Products.PageCount);
}
這個(gè)事件處理器指定了PagingInformation標(biāo)簽的Text屬性為用戶當(dāng)前訪問(wèn)的頁(yè)面-Products.PageIndex + 1(我們?cè)谶@里+1因?yàn)镻roducts.PageIndex屬性是從0開(kāi)始編號(hào)的)和頁(yè)面總數(shù)(Products.PageCount)。我在DataBound事件處理器而不是PageIndexChanged事件處理器中進(jìn)行這個(gè)操作的原因在于,DataBound事件在每次數(shù)據(jù)綁定到GridView的時(shí)候都會(huì)觸發(fā),而PageIndexChanged僅僅在頁(yè)面切換的時(shí)候觸發(fā)。當(dāng)GridView綁定首頁(yè)的時(shí)候PageIndexChanging還沒(méi)有觸發(fā)(而DataBound事件能觸發(fā))。
好了,用戶現(xiàn)在能看到他們正在訪問(wèn)的頁(yè)面和頁(yè)面總數(shù)。
圖10:顯示當(dāng)前頁(yè)和頁(yè)面總數(shù)
除了Label控件,我們?cè)賮?lái)添加一個(gè)DropDownList控件來(lái)顯示所有的頁(yè)數(shù)并選定當(dāng)前瀏覽的頁(yè)面。這樣,用戶就能選擇DropDownList中的某一選項(xiàng)來(lái)快速切換到新的頁(yè)面索引,我們首先拖一個(gè)DropDownList到設(shè)計(jì)器,然后設(shè)置ID屬性為PageList然后選擇啟用AutoPostBack。
接著,在DataBound中加如下代碼:
// Clear out all of the items in the DropDownList
PageList.Items.Clear();
// Add a ListItem for each page
for (int i = 0; i Products.PageCount; i++)
{
// Add the new ListItem
ListItem pageListItem = new ListItem(string.Concat("Page ", i + 1), i.ToString());
PageList.Items.Add(pageListItem);
// select the current item, if needed
if (i == Products.PageIndex)
pageListItem.Selected = true;
}
這段代碼首先清楚了PageList DropDownList中所有的項(xiàng)。既然我們不能預(yù)料到頁(yè)面數(shù)會(huì)不會(huì)改變,看上去這個(gè)操作可能有些多余。但是其它用戶可能會(huì)并發(fā)使用系統(tǒng)來(lái)從Products表中添加或者移除記錄。這樣的插入或者刪除操作可能會(huì)改變數(shù)據(jù)的頁(yè)數(shù)。
接著,我們重新創(chuàng)建頁(yè)數(shù)并選擇GridView PageIndex作為默認(rèn)。我們循環(huán)0到PageCount – 1進(jìn)行新增每一個(gè)ListItem,如果當(dāng)前循環(huán)所以等于GridView的PageIndex屬性的話,我們把這個(gè)項(xiàng)的Selected屬性設(shè)置為true。
最后,我們需要為DropDownList的SelectedIndexChanged事件創(chuàng)建一個(gè)事件處理器。當(dāng)用戶每次選擇了一個(gè)不同頁(yè)面的時(shí)候觸發(fā),我們只需要雙擊設(shè)計(jì)器中的DropDownList來(lái)創(chuàng)建事件處理器,然后添加下面代碼:
protected void PageList_SelectedIndexChanged(object sender, EventArgs e)
{
// Jump to the specified page
Products.PageIndex = Convert.ToInt32(PageList.SelectedValue);
}
如圖11顯示,只不過(guò)是改變GridView的PageIndex屬性并重新綁定GridView。在GridView的DataBound事件處理器中,相應(yīng)的DropDownList ListItem被選擇。
圖11:用戶選擇下拉列表Page 6項(xiàng)后就能切換到第六頁(yè)
Step 5:添加雙向排序支持
增加雙向排序的支持和增加分頁(yè)支持一樣簡(jiǎn)單-只需要選擇GridView 智能標(biāo)簽的Enable Sorting選項(xiàng)(它會(huì)設(shè)置GridView的AllowSorting property 屬性為true)。這樣,GridView每一個(gè)字段的標(biāo)題都會(huì)顯示為L(zhǎng)inkButtons,點(diǎn)擊后頁(yè)面就會(huì)回發(fā),所點(diǎn)擊列的所有數(shù)據(jù)就會(huì)以升序顯示。再次點(diǎn)擊同一個(gè)LinkButton就能以降序顯示。
注意:如果你使用一個(gè)自定義的數(shù)據(jù)訪問(wèn)層而不是強(qiáng)類型DataSet的話,你可能找不到GridView的Enable Sorting選項(xiàng)。因?yàn)锳DO.NET DataTable提供了Sort方法使用指定標(biāo)準(zhǔn)對(duì)DataTable的DataRow進(jìn)行排序,因此強(qiáng)類型DataSet提供了排序支持。
如果你的DAL不返回支持排序的對(duì)象,我們就需要配置ObjectDataSource來(lái)實(shí)現(xiàn)對(duì)業(yè)務(wù)邏輯層返回?cái)?shù)據(jù)的排序。我們將會(huì)在將來(lái)的教程中研究如何排序業(yè)務(wù)邏輯或者數(shù)據(jù)訪問(wèn)層中的數(shù)據(jù)。
排序的LinkButton以HTML鏈接的形式呈現(xiàn),當(dāng)前的顏色(未訪問(wèn)過(guò)未藍(lán)色訪問(wèn)過(guò)為暗紅色)和標(biāo)題的背景色有了沖突,讓我們?cè)O(shè)置所有標(biāo)題中的鏈接在訪問(wèn)過(guò)和未訪問(wèn)的情況下都為白色。我們通過(guò)在Styles.css中添加如下的類來(lái)實(shí)現(xiàn):
.HeaderStyle a, .HeaderStyle a:visited
{
color: White;
}
這段代碼表示,使用HeaderStyle類中的所有鏈接都以白色進(jìn)行顯示。
在定義了CSS后,頁(yè)面瀏覽器中的效果如圖12,圖1也顯示了Price字段標(biāo)題上的鏈接被點(diǎn)擊后的效果。
圖12:結(jié)果根據(jù)UnitPrice以正序形式進(jìn)行排序
研究排序工作方式
所有的GridView字段-BoundField, CheckBoxField, TemplateField等等-都有SortExpression屬性指示當(dāng)標(biāo)題上的排序鏈接點(diǎn)擊后的排序方式。GridView同樣也有一個(gè)SortExpression屬性。當(dāng)排序LinkButton被點(diǎn)擊后,GridView把它的SortExpression設(shè)置為該字段的SortExpression,接著,數(shù)據(jù)就重新按照GridView的SortExpression屬性以一定次序從ObjectDataSource返回。下面列出了用戶排序時(shí)GridView具體的流程步驟:
1.GridView的Sorting event 觸發(fā)
2.GridView的SortExpression 屬性設(shè)置為點(diǎn)擊LinkButton所在字段的SortExpression
3.ObjectDataSource重新從BLL中獲取所有數(shù)據(jù)并根據(jù)GridView的 SortExpression來(lái)排序數(shù)據(jù)
4.GridView的PageIndex被置0,也就是用戶轉(zhuǎn)到了第一頁(yè)數(shù)據(jù)(假設(shè)分頁(yè)是開(kāi)啟的)
5.GridView的Sorted 事件觸發(fā)
和默認(rèn)分頁(yè)方式一樣,默認(rèn)排序方式從BLL中獲取所有數(shù)據(jù)進(jìn)行排序。在未分頁(yè)或者使用默認(rèn)方式分頁(yè)的情況下,我們沒(méi)有辦法改善性能(除了緩存數(shù)據(jù))。然而在后續(xù)教程中,我們能通過(guò)自定義分頁(yè)來(lái)使排序更有效率。
When binding an ObjectDataSource to the GridView through the drop-down list in the GridView's smart tag, each GridView field automatically has its SortExpression property assigned to the name of the data field in the ProductsRow class. For example, the ProductName BoundField's SortExpression is set to ProductName, as shown in the following declarative markup:
如果我們通過(guò)GridView智能標(biāo)簽的下拉框把ObjectDataSource綁定到GridView的話,GridView的字段就會(huì)自動(dòng)把SortExpression屬性設(shè)置為相應(yīng)的ProductsRow類。比如,ProductName BoundField的SortExpression就設(shè)置為ProductName,代碼如下:
asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
一個(gè)字段能通過(guò)清除SortExpression(設(shè)置為空字符串)屬性來(lái)禁止排序。想象下如果我們不希望用戶根據(jù)價(jià)格來(lái)排序產(chǎn)品,我們就可以通過(guò)在代碼標(biāo)簽或者在字段對(duì)話框(點(diǎn)擊GridView智能標(biāo)簽的Edit Columns鏈接)中移除UnitPrice BoundField的SortExpression屬性例子實(shí)現(xiàn)。
圖13:結(jié)果根據(jù)UnitPrice以升序進(jìn)行排序
一旦移除UnitPrice BoundField 的SortExpression屬性,標(biāo)題上就只是文字而不是鏈接了,防止用戶根據(jù)價(jià)格進(jìn)行排序。
圖14:移除了SortExpression屬性,用戶就不能再根據(jù)產(chǎn)品價(jià)格進(jìn)行排序了
編程排序GridView
我們還可以使用GridView的Sort 方法編程對(duì)GridView的內(nèi)容進(jìn)行排序。只需要傳入SortExpression和SortDirection(Ascending或者Descending)即可。
我們關(guān)閉了UnitPrice的排序是考慮到不希望用戶只去買最便宜的東西。然而,我們希望鼓勵(lì)用戶去買最貴的產(chǎn)品,所以我們希望能按照價(jià)格排序但是僅提供從價(jià)格最高到價(jià)格最低這么一種排序方式。
要實(shí)現(xiàn)這樣的需求,我們首先在頁(yè)面上添加一個(gè)Button Web控件,設(shè)置它的ID屬性為SortPriceDescending,Text屬性為“Sort by Price”。然后在設(shè)計(jì)器雙擊按鈕控件來(lái)創(chuàng)建按鈕的Click事件處理器,加入如下代碼:
protected void SortPriceDescending_Click(object sender, EventArgs e)
{
// Sort by UnitPrice in descending order
Products.Sort("UnitPrice", SortDirection.Descending);
}
點(diǎn)擊按鈕頁(yè)面轉(zhuǎn)向第一頁(yè)并以價(jià)格排序,從最貴的到最便宜的(見(jiàn)圖15)。
圖15:點(diǎn)擊按鈕讓產(chǎn)品從最貴到最便宜進(jìn)行排序
總結(jié)
在這個(gè)教程中我們已經(jīng)說(shuō)了如何實(shí)現(xiàn)默認(rèn)分頁(yè)和排序,僅僅需要選擇一個(gè)復(fù)選框來(lái)實(shí)現(xiàn)!當(dāng)用戶排序或者切換頁(yè)面的時(shí)候都會(huì)有類似的工作方式:
1.頁(yè)面回發(fā)
2.數(shù)據(jù)Web控件pre-level的事件觸發(fā)(PageIndexChanging 或者 Sorting)
3.所有信息從ObjectDataSource重新獲取
4.數(shù)據(jù)Web控件post -level的事件觸發(fā)(PageIndexChanged或者 Sorted)
我們實(shí)現(xiàn)了報(bào)表的基本分頁(yè)和排序,但是要取得更好的性能我們還需要?jiǎng)?chuàng)建自定義的分頁(yè)來(lái)或者進(jìn)一步改善分頁(yè)和排序界面。后面的教程會(huì)繼續(xù)討論相關(guān)主題。
編程愉快!
關(guān)于作者
Scott Mitchell,著有六本ASP/ASP.NET方面的書,是4GuysFromRolla.com的創(chuàng)始人,自1998年以來(lái)一直應(yīng)用微軟Web技術(shù)。Scott是個(gè)獨(dú)立的技 術(shù)咨詢顧問(wèn),培訓(xùn)師,作家,最近完成了將由Sams出版社出版的新作,24小時(shí)內(nèi)精通ASP.NET 2.0。他的聯(lián)系電郵為mitchell@4guysfromrolla.com,也可以通過(guò)他的博客http://ScottOnWriting.NET與他聯(lián)系。
您可能感興趣的文章:- asp.net下linkbutton的前后臺(tái)使用方法
- asp.net button 綁定多個(gè)參數(shù)
- 關(guān)于asp.net button按鈕的OnClick和OnClientClick事件
- js觸發(fā)asp.net的Button的Onclick事件應(yīng)用
- ASP.NET 中 Button、LinkButton和ImageButton 三種控件的使用詳解
- 在ASP.NET 2.0中操作數(shù)據(jù)之二十三:基于用戶對(duì)修改數(shù)據(jù)進(jìn)行限制
- 在ASP.NET 2.0中操作數(shù)據(jù)之二十五:大數(shù)據(jù)量時(shí)提高分頁(yè)的效率
- 在ASP.NET 2.0中操作數(shù)據(jù)之二十六:排序自定義分頁(yè)數(shù)據(jù)
- 在ASP.NET 2.0中操作數(shù)據(jù)之二十七:創(chuàng)建自定義排序用戶界面
- 在ASP.NET 2.0中操作數(shù)據(jù)之二十八:GridView里的Button