ASP.NET 3.5's ListView and DataPager—Part3:用ListView控件排序數據

本文英文原版及代碼下載:
http://aspnet.4guysfromrolla.com/articles/011608-1.aspx

ASP.NET 3.5's ListView and DataPager—Part3:用ListView控件排序數據

導言:

當使用數據源控件綁定數據到一個GridView控件時,要想啓用排序功能的話只需要在GridView的智能標籤裏選"Enable Sorting"即可.啓用了之後,GridView控件裏每列的表頭都將轉變成一個LinkButton,當點擊時就會引發一個回傳,按照該列進行排序後重新綁定到GridView控件.

同樣的,要想在ListView控件裏啓用排序功能也是很簡單的,甚至不用你寫一行代碼.但是我們遇到的主要問題是,與GridView控件不同,ListView控件裏沒有沒有預先定義好的列(pre-defined columns).因此我們要自己定義並貫徹排序界面(sorting interface),完成這些工作之後,ListView控件就可以在內部處理排序邏輯而不用我們寫代碼了.當然,在一些更高級的場合下,我們需要手動排序或者通過編程的方式指定在內部排序數據要依據的排序表達式.在排序之前,ListView控件將先觸發Sorting事件處理器(Sorting event handler),在該事件處理器裏我們可以添加任何與排序相關的邏輯.此外,還可以通過Sort method來通過編程調用ListView控件的排序邏輯.

在本文我們將考察如何在ListView控件裏啓用排序功能。我們首先考察ListView的排序函數(sorting functionality),接下來我們在考察如何在更高級的場合以編程的方式通過Sort method調用排序邏輯.

Sorting Basics

ListView排序所用到的核心概念與其它View Web controls,比如 GridView, DetailsView,和FormView等是一樣的.作爲啓動器(starters),ListView控件有一個Sort(sortExpression, sortDirection) method,參數爲一個string類型的sortExpression以及一個SortDirection enumeration(值爲Ascending 和 Descending),調用該Sort method將觸發ListView控件的Sorting event.

如果ListView是綁定到一個數據源控件(比如SqlDataSource或ObjectDataSource ),那麼數據源控件將負責對數據進行排序,然後這些排序後的數據再重新綁定到ListView控件.簡單的說,如果你使用的是數據源控件,那麼不需要我們寫一行代碼,ListView就可以執行排序——所有的工作由ListView以及數據源控件自動的處理.

如果ListView是通過編程的方式綁定數據的——也就是說我們寫代碼檢索數據再指定ListView控件的DataSource屬性,再調用ListView的DataBind()方法——那麼我們就要自己負責對數據進行排序再將排好序的數據重新綁定到ListView控件.爲此,我們需要爲ListView的Sorting event創建一個事件處理器,在該事件處理器裏我們將按指定的排序來檢索數據並重新綁定到ListView.我們將在本文後面考察如何創建一個Sorting事件處理器(實際上,在更高級的排序場合才這樣做。在此,我們的示例代碼使用的是一個數據源控件)

爲了開啓ListView的排序工作流程(sorting workflow)有2個辦法,一是調用Sort method;二是在ListView控件的LayoutTemplate模板裏添加一個LinkButton, Button, 或ImageButton按鈕,當點擊按鈕時將觸發回傳並開啓排序工作流程.爲此,LinkButton, Button, 或ImageButton按鈕的CommandName屬性必須設置爲"Sort",而CommandArgument屬性要設置成作爲排序依據的那個數據列(data field).

一個簡單的,隨意排序的示例

爲演示如何使用ListView控件內置的排序機制,我們來看一個例子(該示例可以在本文結尾處下載到).我們將Part1裏的例子進行擴展以包含一個排序界面.具體來說,我們添加2個排序選項:按ProductName和UnitPrice進行排序.爲此,僅僅需要在ListView控件的LayoutTemplate模板裏添加2個LinkButtons (或Buttons 或ImageButtons都行),並對CommandName 和 CommandArgument屬性賦相應的值.

<asp:ListView ID="ProductList" runat="server" DataSourceID="ProductDataSource">
   <LayoutTemplate>
      <h3>Product Listing</h3>
      [<asp:LinkButton runat="server" ID="SortByName" CommandName="Sort"
                     CommandArgument="ProductName">Sort by Name</asp:LinkButton>]
      | [<asp:LinkButton runat="server" ID="SortByPrice" CommandName="Sort"
                     CommandArgument="UnitPrice">Sort by Price</asp:LinkButton>]

      <blockquote>
         <asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
      </blockquote>
   </LayoutTemplate>

   ...
</asp:ListView> 

(注意:爲簡化起見,我省略掉了ListView的大部分聲明代碼,而將注意力集中到這2個用來排序的LinkButtons.此外我們也省略掉了綁定到該ListView控件的AccessDataSource控件)

請注意,這2個排序按鈕的CommandName屬性都設置爲Sort,而CommandArgument屬性則設置爲相應的數據列的名字.當點擊其中一個按鈕時,頁面回傳,ListView控件將自動的調用其Sort method方法,並將LinkButton的 CommandArgument屬性值傳入作爲排序表達式(sort expression).而排序方向則由一個內部變量控制,當用相同的排序表達式連續2次進行排序時,排序方向將互相轉換.因此,如果訪問用戶連續2次點擊"Sort by Price"鏈接,第一次點擊時產品將按升序進行排序(也就是從最便宜到最貴的方向),第二次點擊時排序方向將變爲按降序進行排序.

下面的2個截屏顯示的是實際點擊排序LinkButtons的情形,第一個截屏是第一次點擊"Sort by Price" 時的情況,產品按升序進行排列.


                                                                             圖1
第二個截屏顯示的是再次點擊的情形,這次是按降序排列的.


                                                             圖2


通過Sort Method來排序

在前面的示例我們考察了當用戶點擊一個LinkButton, Button, 或ImageButton控件時如何讓ListView做出響應以排序數據.不過在某些情況下,我們需要以編程的方式啓動ListView的排序工作流程.比如,當頁面初次加載時我們想排序數據,或者將某些用戶界面元素呈現爲某種樣式,那麼我們就想對結果排序了.爲此,我們可以調用ListView的Sort method方法並傳入sort expression以及排序方向.

爲演示該方法,我們在上面的示例裏添加一個Button Web control,當點擊時按CategoryName列對結果進行排序.我們僅僅需要添加一個Button Web control,創建它的Click event handler,在該event handler 裏我們調用ListView控件的Sort method,傳入"CategoryName"作爲sort expression ,排序方向爲SortDirection.Ascending,要做的就這些了.

Protected Sub SortByCallingSortMethodButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles

SortByCallingSortMethodButton.Click
   'Sort the ListView by the CategoryName field in ascending order
   ProductList.Sort("CategoryName", SortDirection.Ascending)
End Sub

點擊該按鈕將導致頁面回傳,並調用Sort method,該方法又啓動排序工作流程.效果就好像我們在LayoutTemplate模板裏添加了一個LinkButton,並分別設置其CommandName和CommandArgument屬性爲Sort 和 "CategoryName"一樣.


                                                             圖3


爲ListView的Sorting Event事件創建一個Event Handler

在某些情況下,我們需要在ListView的排序工作流程裏執行代碼,爲此我們可以爲ListView的Sorting event事件創建一個事件處理器,當啓動排序工作流程時就會觸發該事件.如果ListView的數據是通過編程的方式來進行綁定的,那麼我們就需要創建一個Sorting event handler來對數據重新排序並重新綁定到ListView數據.即使我們聲明使用的是數據源控件來綁定數據的,我們也可以在排序工作流程裏執行自定義排序邏輯

.在本文下載代碼裏,包含了一個示例,它可以“記住”最近5次運用的排序依據並將這5個排序依據顯示在頁面上的一系列LinkButton控件上.當點擊其中一個LinkButtons時將根據對應的排序依據再次執行排序.爲實現該功能,我需要爲Sorting event事件創建一個event handler,這樣一來我們就可以將剛纔應用的sort expression和排序方向記錄下來.

每一條用戶剛剛應用過的排序依據都將由一個名爲SortHistory的object對象進行登記記錄,該對象實際上是我在App_Code文件夾裏創建的一個類,該類有SortExpression 和 SortDirection屬性且都是隻讀的,該類將SortExpression和SortDirection屬性以string的形式返回,此外該類還將返回一個格式化字符串(formatted string),以表明我們的意圖.打個比方,如果SortExpression 和 SortDirection屬性的值分別爲 "CategoryName" 和SortDirection.Descending,那麼該格式化字符串將返回一個更爲友好、明瞭的輸出: "Category (in descending order)".

同時在App_Code文件夾我還創建了一個SortHistoryQueue object對象,它最多可以存儲5個SortHistory對象.我們把一個SortHistoryQueue的實例存儲在一個Session裏,那麼當頁面回傳時,針對某個用戶的排序依據就不會丟失,且可以跨頁面傳遞.

除了使用Sorting event handler外,演示代碼裏還使用了Sort method。就象我在前面提過的那樣,用戶最近的5個排序依據展示在一系列的LinkButtons控件上,這是用一個Repeater控件來實現的.點擊一個LinkButton控件將引發回傳並觸發Repeater的ItemCommand event事件.我爲該事件創建了一個事件處理器,在該事件處理器了調用ListView控件的Sort method方法,排序依據就是點擊的那個LinkButtons控件對應的排序依據.

下面的截屏顯示的是實際運用的情況,第一個圖輸出的是最近使用的5個排序依據.


                                                              圖4
第二圖是點擊了"Sort by Name"按鈕後的情況,注意最上面那個LinkButton按鈕變成了"Name (in ascending order)"(當然,實際上是按ProductName進行升序排序的)


                                                                               圖5


結語:

在本文我們考察瞭如何在一個ListView控件裏排序數據.與GridView, DetailsView,和FormView控件一樣,不用寫一行代碼我們就可以對ListView的數據排序。正如我們在第一個示例裏看到的那樣,我們所要做的就是創建一個sorting interface:添加Buttons, LinkButtons, 或ImageButtons控件,並設置恰當的CommandName 和 CommandArgument屬性.點擊這些按鈕後將產生頁面回傳,並觸發ListView的排序工作流程,

當然我們也可以顯式的調用Sort method, 傳入相關的sort expression和排序方向.在某些情況下我們需要手動排序,或執行其它與排序相關的邏輯. 在這種情況下,只需要爲ListView控件的Sorting event事件創建一個事件處理器(在事件在排序流程啓動時觸發).

祝編程快樂!
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章