導言
DataList和Repeater數據分頁裡我們學習了如何在DataList裡添加分頁功能。我們在ProductsBLL類裡創建了一個名為GetProductsAsPagedDataSource的方法,它返回一個PagedDataSource對象。當綁定到DataList或Repeater時,他們將只顯示請求頁的數據。這個技術和GridView,DetailsView,FormView的內置分頁功能原理差不多。
除了分頁外,GridView還提供了內置的排序功能,而DataList和Repeater都沒有。然而排序功能可以通過一點點代碼就實現。本章我們將學習如何在DataList和Repeater裡實現排序功能,我們還將創建一個同時支持分頁和排序的DataList或Repeater。
回顧一下排序
如我們在分頁和排序報表數據裡看到的,GridView提供了排序的支持。每個GridView的字段可以有一個關聯的SortExpression,它指明了對數據進行排序依據的字段。當GridView的AllowSorting屬性設為true時,每個包含SortExpression 屬性的GridView的字段的header都表現為一個LinkButton。當點一個header時,頁面postback,數據會根據被點字段的SortExpression進行排序。另外,SortDirection屬性指明了數據是升序或降序。
當將GridView綁定到數據源控件時,它會將SortExpression和SortDirection傳給數據源控件。數據源控件獲取數據並根據SortExpression和SortDirection進行排序。然後將數據返回給GridView。
在DataList或Repeater裡實現這個功能,我們需要:
創建一個排序界面
將排序的字段和方向(升序或降序)記下
指導ObjectDataSource根據特定字段排序
我們將在第三和四步來處理上面三個步驟。然後我們將看看如何讓DataList或Repeater同時支持這兩個功能(分頁和排序)。
第二步: 在 Repeater裡顯示 Products
在實現排序功能前,首先創建一個列出所有product的Repeater。打開PagingSortingDataListRepeater文件夾裡的Sorting.aspx頁。添加一個Repeater,將ID設為SortableProducts。從智能標簽裡創建一個名為ProductsDataSource的ObjectDataSource。用ProductsBLL類的GetProducts()方法配置它。在INSERT, UPDATE, DELETE標簽的下拉列表裡選擇“(None)”。
圖 1: 創建 ObjectDataSource
圖 2: 在 UPDATE, INSERT, DELETE 標簽的下拉列表裡選擇 “(None)”
在綁定到數據源後,Visual Studio沒有自動為Repeater創建ItemTemplate,這點和DataList不一樣。而且由於Repeater控件的智能標簽裡沒有象DataList裡那樣的“Edit Templates”選項,因此我們需要直接添加聲明代碼。我們使用和前一章一樣的ItemTemplate,它顯示product的 name, supplier, category。
現在你的Repeater和ObjectDataSource的聲明標記看起來應該和下面差不多:
<asp:Repeater ID="SortableProducts" DataSourceID="ProductsDataSource" EnableViewState="False" runat="server"> <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> </asp:Repeater> <asp:ObjectDataSource ID="ProductsDataSource" runat="server" OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL" SelectMethod="GetProducts"> </asp:ObjectDataSource>
圖 3 是現在浏覽該頁的樣子。
圖 3: 顯示 Product的 Name, Supplier, Category
第三步: 指導 ObjectDataSource 對數據進行排序
為了讓Repeater裡顯示的數據排序,我們需要將數據排序的sort expression告訴ObjectDataSource。在ObjectDataSource獲取數據前,首先激發的是Selecting event,它給我們提供了一個指定sort expression的機會。Selecting event handler 有一個ObjectDataSourceSelectingEventArgs 類型的參數,它有一個名為Arguments的 DataSourceSelectArguments類型的屬性.。DataSourceSelectArguments類被設計用來將數據相關的請求從數據的消費者傳給數據源控件,它有一個SortExpression property。
創建一個Selecting event handler,用以下代碼將排序的信息從ASP.NET頁傳給ObjectDataSource:
protected void ProductsDataSource_Selecting (object sender, ObjectDataSourceSelectingEventArgs e) { e.Arguments.SortExpression = sortExpression; }
sortExpression 需要賦值為排序字段的名字(例如“ProductName”)。它沒有排序方向相關的屬性,因此如果需要以降序來排序,將“DESC”附加在sortExpression 的值後面(比如“ProductName DESC”)。
繼續試一下硬編碼將sortExpression 賦為不同的值,並浏覽頁面 。如圖4,當使用“ProductName DESC”作為sortExpression時,product會根據name的字母順序反向排序。
圖 4: Product 根據Name 的字母順序反向排序
第四步: 創建排序界面並記下Sort Expression 和 Direction
開啟GridView的排序支持會將每個可排序的字段的header text轉換為一個LinkButton,當被點擊時,會進行相對應的排序。這樣的排序對GridView來說是很合理的,因為它的數據是以列的形式整齊的展示。而對DataList和Repeater來說,需要不同的排序界面。一個常見的數據列表(相對於數據網格)的排序界面是使用一個提供排序字段的下拉列表。我們本章將完成這樣的界面。
在SortableProducts Repeater上方添加一個DropDownList,將ID設為SortBy。在屬性窗口裡點Items屬性打開ListItem集合編輯器。添加ListItems,讓數據根據ProductName, CategoryName, SupplierName 字段排序。同時添加ListItem讓product根據反向的name的順序排序。
ListItem的Text屬性可以設為任何值(比如“Name”),但是Value必須設為數據字段的名字(比如“ProductName”)。添加字符串“DESC”到數據字段名字後面,來讓結果以降序排序,比如“ProductName DESC”。
圖 5:為每個可排序的字段添加 ListItem
最後在DropDownList的右邊添加一個Button。將ID設為RefreshRepeater,Text設為“Refresh”。
完成這些後,DropDownList和Button的聲明語法看起來應該和下面差不多:
<asp:DropDownList ID="SortBy" runat="server"> <asp:ListItem Value="ProductName">Name</asp:ListItem> <asp:ListItem Value="ProductName DESC">Name (Reverse Order) </asp:ListItem> <asp:ListItem Value="CategoryName">Category</asp:ListItem> <asp:ListItem Value="SupplierName">Supplier</asp:ListItem> </asp:DropDownList> <asp:Button runat="server" ID="RefreshRepeater" Text="Refresh" /> 完成DropDownList後,我們需要更新ObjectDataSource的Selecting event handler,來讓它使用選擇的SortBy ListItem的Value作為sort expression,代替前面的硬編碼。 protected void ProductsDataSource_Selecting (object sender, ObjectDataSourceSelectingEventArgs e) { // Have the ObjectDataSource sort the results by the selected // sort expression e.Arguments.SortExpression = SortBy.SelectedValue; }
現在第一次浏覽頁的時候,由於默認的SortBy ListItem 的值為ProductName,因此product會根據ProductName字段來排序。見圖6。選擇一個其它的項–比如“Category”–然後點Refresh,這時會postback,數據會根據category name來重新排序,見圖7。
圖 6: 第一次 Products 根據 Name 排序
圖 7: 現在 Products 根據 Category 來排序
注意:點Refresh button會讓數據重新排序是因為Repeater的view state被禁用了,因此Repeater在每次postback時重新綁定到數據源。如果你開啟Repeater的view state,這時改變drop-down list不會對排序有任何影響。為了修復這個問題,你可以為Refresh Button的 Click event創建一個event handler,來重新綁定Repeater到數據源(調用Repeater的DataBind()方法)。
記下Sort Expression 和 Direction(排序表達式和排序方向)
如果包含可排序的DataList或Repeater的頁可能有其它和排序無關的postback發生,那麼我們需要在postback過程中記下sort expression 和 direction。比如,我們將本章的Repeater修改成為每個product包含一個Delete button。當用戶點Delete button時我們會執行一些代碼來刪除選擇的product,然後將數據綁定到Repeater。如果排序的信息在postback過程中沒有被保存下來,那麼顯示的數據會回復到最初的排序狀態。
本章裡,DropDownList隱式的為我們將sort expression 和 direction保存在它的view state裡。如果我們使用不同的排序界面–LinkButton提供不同的排序選項–我們就需要在postback過程中記下排序的信息。這個可以通過將排序的參數記在page的view state裡,或者記在querystring裡,或者通過一些其它狀態保存機制來實現。
祝編程快樂!
作者簡介
本系列教程作者 Scott Mitchell,著有六本ASP/ASP.NET方面的書,是4GuysFromRolla.com的創始人,自1998年以來一直應用 微軟Web技術。大家可以點擊查看全部教程《[翻譯]Scott Mitchell 的ASP.NET 2.0數據教程》,希望對大家的學習ASP.NET有所幫助。