在ASP.NET 2.0中操作數(shù)據(jù)之四十二:DataList和Repeater數(shù)據(jù)排序(一)
導(dǎo)言
DataList和Repeater數(shù)據(jù)分頁(yè)里我們學(xué)習(xí)了如何在DataList里添加分頁(yè)功能。我們?cè)赑roductsBLL類(lèi)里創(chuàng)建了一個(gè)名為GetProductsAsPagedDataSource的方法,它返回一個(gè)PagedDataSource對(duì)象。當(dāng)綁定到DataList或Repeater時(shí),他們將只顯示請(qǐng)求頁(yè)的數(shù)據(jù)。這個(gè)技術(shù)和GridView,DetailsView,F(xiàn)ormView的內(nèi)置分頁(yè)功能原理差不多。
除了分頁(yè)外,GridView還提供了內(nèi)置的排序功能,而DataList和Repeater都沒(méi)有。然而排序功能可以通過(guò)一點(diǎn)點(diǎn)代碼就實(shí)現(xiàn)。本章我們將學(xué)習(xí)如何在DataList和Repeater里實(shí)現(xiàn)排序功能,我們還將創(chuàng)建一個(gè)同時(shí)支持分頁(yè)和排序的DataList或Repeater。
回顧一下排序
如我們?cè)诜猪?yè)和排序報(bào)表數(shù)據(jù)里看到的,GridView提供了排序的支持。每個(gè)GridView的字段可以有一個(gè)關(guān)聯(lián)的SortExpression,它指明了對(duì)數(shù)據(jù)進(jìn)行排序依據(jù)的字段。當(dāng)GridView的AllowSorting屬性設(shè)為true時(shí),每個(gè)包含SortExpression 屬性的GridView的字段的header都表現(xiàn)為一個(gè)LinkButton。當(dāng)點(diǎn)一個(gè)header時(shí),頁(yè)面postback,數(shù)據(jù)會(huì)根據(jù)被點(diǎn)字段的SortExpression進(jìn)行排序。另外,SortDirection屬性指明了數(shù)據(jù)是升序或降序。
當(dāng)將GridView綁定到數(shù)據(jù)源控件時(shí),它會(huì)將SortExpression和SortDirection傳給數(shù)據(jù)源控件。數(shù)據(jù)源控件獲取數(shù)據(jù)并根據(jù)SortExpression和SortDirection進(jìn)行排序。然后將數(shù)據(jù)返回給GridView。
在DataList或Repeater里實(shí)現(xiàn)這個(gè)功能,我們需要:
創(chuàng)建一個(gè)排序界面
將排序的字段和方向(升序或降序)記下
指導(dǎo)ObjectDataSource根據(jù)特定字段排序
我們將在第三和四步來(lái)處理上面三個(gè)步驟。然后我們將看看如何讓DataList或Repeater同時(shí)支持這兩個(gè)功能(分頁(yè)和排序)。
第二步: 在 Repeater里顯示 Products
在實(shí)現(xiàn)排序功能前,首先創(chuàng)建一個(gè)列出所有product的Repeater。打開(kāi)PagingSortingDataListRepeater文件夾里的Sorting.aspx頁(yè)。添加一個(gè)Repeater,將ID設(shè)為SortableProducts。從智能標(biāo)簽里創(chuàng)建一個(gè)名為ProductsDataSource的ObjectDataSource。用ProductsBLL類(lèi)的GetProducts()方法配置它。在INSERT, UPDATE, DELETE標(biāo)簽的下拉列表里選擇“(None)”。
圖 1: 創(chuàng)建 ObjectDataSource
圖 2: 在 UPDATE, INSERT, DELETE 標(biāo)簽的下拉列表里選擇 “(None)”
在綁定到數(shù)據(jù)源后,Visual Studio沒(méi)有自動(dòng)為Repeater創(chuàng)建ItemTemplate,這點(diǎn)和DataList不一樣。而且由于Repeater控件的智能標(biāo)簽里沒(méi)有象DataList里那樣的“Edit Templates”選項(xiàng),因此我們需要直接添加聲明代碼。我們使用和前一章一樣的ItemTemplate,它顯示product的 name, supplier, category。
現(xiàn)在你的Repeater和ObjectDataSource的聲明標(biāo)記看起來(lái)應(yīng)該和下面差不多:
<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 是現(xiàn)在瀏覽該頁(yè)的樣子。
圖 3: 顯示 Product的 Name, Supplier, Category
第三步: 指導(dǎo) ObjectDataSource 對(duì)數(shù)據(jù)進(jìn)行排序
為了讓Repeater里顯示的數(shù)據(jù)排序,我們需要將數(shù)據(jù)排序的sort expression告訴ObjectDataSource。在ObjectDataSource獲取數(shù)據(jù)前,首先激發(fā)的是Selecting event,它給我們提供了一個(gè)指定sort expression的機(jī)會(huì)。Selecting event handler 有一個(gè)ObjectDataSourceSelectingEventArgs 類(lèi)型的參數(shù),它有一個(gè)名為Arguments的 DataSourceSelectArguments類(lèi)型的屬性.。DataSourceSelectArguments類(lèi)被設(shè)計(jì)用來(lái)將數(shù)據(jù)相關(guān)的請(qǐng)求從數(shù)據(jù)的消費(fèi)者傳給數(shù)據(jù)源控件,它有一個(gè)SortExpression property。
創(chuàng)建一個(gè)Selecting event handler,用以下代碼將排序的信息從ASP.NET頁(yè)傳給ObjectDataSource:
protected void ProductsDataSource_Selecting (object sender, ObjectDataSourceSelectingEventArgs e) { e.Arguments.SortExpression = sortExpression; }
sortExpression 需要賦值為排序字段的名字(例如“ProductName”)。它沒(méi)有排序方向相關(guān)的屬性,因此如果需要以降序來(lái)排序,將“DESC”附加在sortExpression 的值后面(比如“ProductName DESC”)。
繼續(xù)試一下硬編碼將sortExpression 賦為不同的值,并瀏覽頁(yè)面 。如圖4,當(dāng)使用“ProductName DESC”作為sortExpression時(shí),product會(huì)根據(jù)name的字母順序反向排序。
圖 4: Product 根據(jù)Name 的字母順序反向排序
第四步: 創(chuàng)建排序界面并記下Sort Expression 和 Direction
開(kāi)啟GridView的排序支持會(huì)將每個(gè)可排序的字段的header text轉(zhuǎn)換為一個(gè)LinkButton,當(dāng)被點(diǎn)擊時(shí),會(huì)進(jìn)行相對(duì)應(yīng)的排序。這樣的排序?qū)ridView來(lái)說(shuō)是很合理的,因?yàn)樗臄?shù)據(jù)是以列的形式整齊的展示。而對(duì)DataList和Repeater來(lái)說(shuō),需要不同的排序界面。一個(gè)常見(jiàn)的數(shù)據(jù)列表(相對(duì)于數(shù)據(jù)網(wǎng)格)的排序界面是使用一個(gè)提供排序字段的下拉列表。我們本章將完成這樣的界面。
在SortableProducts Repeater上方添加一個(gè)DropDownList,將ID設(shè)為SortBy。在屬性窗口里點(diǎn)Items屬性打開(kāi)ListItem集合編輯器。添加ListItems,讓數(shù)據(jù)根據(jù)ProductName, CategoryName, SupplierName 字段排序。同時(shí)添加ListItem讓product根據(jù)反向的name的順序排序。
ListItem的Text屬性可以設(shè)為任何值(比如“Name”),但是Value必須設(shè)為數(shù)據(jù)字段的名字(比如“ProductName”)。添加字符串“DESC”到數(shù)據(jù)字段名字后面,來(lái)讓結(jié)果以降序排序,比如“ProductName DESC”。
圖 5:為每個(gè)可排序的字段添加 ListItem
最后在DropDownList的右邊添加一個(gè)Button。將ID設(shè)為RefreshRepeater,Text設(shè)為“Refresh”。
完成這些后,DropDownList和Button的聲明語(yǔ)法看起來(lái)應(yīng)該和下面差不多:
<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,來(lái)讓它使用選擇的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; }
現(xiàn)在第一次瀏覽頁(yè)的時(shí)候,由于默認(rèn)的SortBy ListItem 的值為ProductName,因此product會(huì)根據(jù)ProductName字段來(lái)排序。見(jiàn)圖6。選擇一個(gè)其它的項(xiàng)–比如“Category”–然后點(diǎn)Refresh,這時(shí)會(huì)postback,數(shù)據(jù)會(huì)根據(jù)category name來(lái)重新排序,見(jiàn)圖7。
圖 6: 第一次 Products 根據(jù) Name 排序
圖 7: 現(xiàn)在 Products 根據(jù) Category 來(lái)排序
注意:點(diǎn)Refresh button會(huì)讓數(shù)據(jù)重新排序是因?yàn)镽epeater的view state被禁用了,因此Repeater在每次postback時(shí)重新綁定到數(shù)據(jù)源。如果你開(kāi)啟Repeater的view state,這時(shí)改變drop-down list不會(huì)對(duì)排序有任何影響。為了修復(fù)這個(gè)問(wèn)題,你可以為Refresh Button的 Click event創(chuàng)建一個(gè)event handler,來(lái)重新綁定Repeater到數(shù)據(jù)源(調(diào)用Repeater的DataBind()方法)。
記下Sort Expression 和 Direction(排序表達(dá)式和排序方向)
如果包含可排序的DataList或Repeater的頁(yè)可能有其它和排序無(wú)關(guān)的postback發(fā)生,那么我們需要在postback過(guò)程中記下sort expression 和 direction。比如,我們將本章的Repeater修改成為每個(gè)product包含一個(gè)Delete button。當(dāng)用戶(hù)點(diǎn)Delete button時(shí)我們會(huì)執(zhí)行一些代碼來(lái)刪除選擇的product,然后將數(shù)據(jù)綁定到Repeater。如果排序的信息在postback過(guò)程中沒(méi)有被保存下來(lái),那么顯示的數(shù)據(jù)會(huì)回復(fù)到最初的排序狀態(tài)。
本章里,DropDownList隱式的為我們將sort expression 和 direction保存在它的view state里。如果我們使用不同的排序界面–LinkButton提供不同的排序選項(xiàng)–我們就需要在postback過(guò)程中記下排序的信息。這個(gè)可以通過(guò)將排序的參數(shù)記在page的view state里,或者記在querystring里,或者通過(guò)一些其它狀態(tài)保存機(jī)制來(lái)實(shí)現(xiàn)。
祝編程快樂(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有所幫助。
- ASP.NET2.0數(shù)據(jù)庫(kù)入門(mén)之SqlDataSource
- SqlDataSource 鏈接Access 數(shù)據(jù)
- aspx中的mysql操作類(lèi)sqldatasource使用示例分享
- 在ASP.NET 2.0中操作數(shù)據(jù)之三十九:在DataList的編輯界面里添加驗(yàn)證控件
- 在ASP.NET 2.0中操作數(shù)據(jù)之四十:自定義DataList編輯界面
- 在ASP.NET 2.0中操作數(shù)據(jù)之四十一:DataList和Repeater數(shù)據(jù)分頁(yè)
- 在ASP.NET 2.0中操作數(shù)據(jù)之四十三:DataList和Repeater數(shù)據(jù)排序(二)
- 在ASP.NET 2.0中操作數(shù)據(jù)之四十四:DataList和Repeater數(shù)據(jù)排序(三)
- 在ASP.NET 2.0中操作數(shù)據(jù)之四十五:DataList和Repeater里的自定義Button
- 在ASP.NET 2.0中操作數(shù)據(jù)之四十六:使用SqlDataSource控件檢索數(shù)據(jù)
- 在ASP.NET 2.0中操作數(shù)據(jù)之四十七:用SqlDataSource控件插入、更新、刪除數(shù)據(jù)
相關(guān)文章
《解剖PetShop》之一:PetShop的系統(tǒng)架構(gòu)設(shè)計(jì)
PetShop是一個(gè)范例,微軟用它來(lái)展示.Net企業(yè)系統(tǒng)開(kāi)發(fā)的能力。本文主要講解PetShop4.0的系統(tǒng)架構(gòu)設(shè)計(jì),需要的朋友可以參考下。2016-05-05在ASP.NET中調(diào)用存儲(chǔ)過(guò)程方法新解
在ASP.NET中調(diào)用存儲(chǔ)過(guò)程方法新解...2006-10-10解讀ASP.NET 5 & MVC6系列教程(8):Session與Caching
這篇文章主要介紹了ASP.NET 5 中的Session與Caching配置和使用,需要的朋友可以參考下2016-06-06在ASP.NET 2.0中操作數(shù)據(jù)之十三:在DetailsView控件中使用TemplateField
就像在GridView中那樣,DetailsView控件也可以同樣的使用TemplateField。本文用兩個(gè)TemplateField來(lái)演示在它的使用方法。2016-05-05NopCommerce架構(gòu)分析之(五)Model綁定Action參數(shù)
本文主要介紹NopCommerce中在請(qǐng)求Controller的Action方法前,通過(guò)ModelBinder將Model進(jìn)行綁定,以便后續(xù)捕捉到數(shù)據(jù),轉(zhuǎn)化成對(duì)象,再進(jìn)行處理。2016-04-04在ASP.NET 2.0中操作數(shù)據(jù)之三:創(chuàng)建母版頁(yè)和站點(diǎn)導(dǎo)航
本文主要介紹在ASP.NET如何創(chuàng)建母版頁(yè)以及站點(diǎn)地圖等操作,母版頁(yè)的實(shí)現(xiàn)的功能有點(diǎn)類(lèi)似自定義用戶(hù)控件,可以實(shí)現(xiàn)網(wǎng)站頁(yè)面統(tǒng)一的設(shè)計(jì)和布局。2016-04-04在ASP.NET 2.0中操作數(shù)據(jù)之五十六:使用ObjectDataSource緩存數(shù)據(jù)
本文主要講解ASP.NET 2.0中ObjectDataSource內(nèi)建的緩存功能,通過(guò)簡(jiǎn)單的配置,我們可以將ObjectDataSource調(diào)用SelectMethod方法得到的數(shù)據(jù)進(jìn)行緩存。2016-05-05在ASP.NET 2.0中操作數(shù)據(jù)之四十八:對(duì)SqlDataSource控件使用開(kāi)放式并發(fā)
本文主要講解ASP.NET 2.0中SqlDataSource控件通過(guò)配合SQL語(yǔ)句達(dá)到控制開(kāi)放式并發(fā)的目的,通過(guò)在UPDATE和DELETE語(yǔ)句里擴(kuò)展WHERE字句,SqlDataSource能應(yīng)對(duì)絕大部分情況。2016-05-05ASP.NET MVC4入門(mén)教程(二):添加一個(gè)控制器
本文對(duì)MVC模式(模型-視圖-控制器)做了簡(jiǎn)單的介紹,并演示如何添加一個(gè)控制器。2016-04-04在ASP.NET 2.0中操作數(shù)據(jù)之七十三:用Managed Code創(chuàng)建存儲(chǔ)過(guò)程和用戶(hù)自定義函數(shù)(上部分)
Microsoft SQL Server 2005整合了Common Language Runtime (CLR),它允許用managed code來(lái)創(chuàng)建數(shù)據(jù)庫(kù)對(duì)象,本文主要介紹了如何使用managed code創(chuàng)建存儲(chǔ)過(guò)程。2016-05-05