ASP.NET2.0移動開發之列表控件
友情提醒:閱讀本文之前請首先閱讀《ASP.NET 2.0移動開發之設備篩選器的應用》
概述
在很多情況下,我們都會使用到列表控件來方便用戶選擇一些選項。例如在某網站上注冊新用戶時,通常會詢問你的性別是"男"還是"女",這時我們用單項按鈕以供用戶做出相應的選擇。還有當你填寫自己的家庭地址時,通常會使用到一個包含各省省名的下拉列表來供用戶直接選擇,這樣可以減少用戶的輸入量。上述的這些單項按鈕和下拉列表都在ASP.NET移動程序中都是以列表控件的形式存在的。我們可以使用列表控件來呈現各種形式(單項、多選、下拉列表)的列表,以供用戶選擇和使用。但是在ASP.NET 2.0移動開發工具包中,只有三個列表控件,分別為SelectionList 、List和ObjectList 控件。雖然沒有ASP.NET 2.0中那么多類型的列表控件,但是我們卻可以使用SelectionList 、List和ObjectList這三個列表控件實現單項、多選等幾乎所有的功能。在本系列文章中將探討這三個控件的一些基本功能和使用方法,并說明這三個控件相似之處及異同點。
圖1是SelectionList 、List和ObjectList三個控件在類的繼承上的關系:
上面的三個列表控件中,SelectionList是最簡單的,但是它可以以各種不同的類型進行呈現,因此具有很大的靈活度,以供不同的需求使用應用的列表類型。同時因為SelectionList控件不支持分頁功能,所以在包含多個列表項的情況下,該控件就顯得力不從心了。還有一點要需要重點說明的是,SelectionList是這三個列表控件中唯一支持多選的。而且該控件還可以以下拉列表的形式進行呈現,也可以以單項和多選框的方式進行呈現,當然這種呈現格式必須要被移動設備上的瀏覽器所接受。在一些WML瀏覽器上,只支持一些特殊的呈現形式,例如單項和多選按鈕,并不支持下拉列表這種呈現形式。圖2演示了下拉列表在不同瀏覽器上呈現時所存在的差別。
List列表控件支持分頁功能,這就意味著它支持列表項較多的列表。它只可以以項目符號列表或編號列表的形式進行呈現(只要瀏覽器支持即可)。除了之外,其它的被SelectionList支持的列表形式(例如下拉列表),在List中均無法實現。圖3中List列表控件就是以編號列表的形式呈現的,并且支持分頁功能。
在上述三個列表控件中最復雜的當屬ObjectList 控件了。SelectionList和List控件允許你使用服務器控件語法靜態地聲明列表項,但是ObjectList控件是無法采用這種方式來添加列表項的,你必須在ObjectLis列表控件與相應的數據源綁定后,再通過代碼將列表項添加到列表中。ObjectList 控件允許一個列表項中同時顯示多個字段,這是其它兩個控件所不具備的,它們只允許每個列表項只顯示一個字段的信息。除此之外,ObjectList 控件中的每個列表項還可以和多個命令相關聯,其它兩個控件所不具備的功能。
下表概括了上述三個控件的主要功能:
采用不同的方式構建列表
在開始探究每個列表控件的具體用法時,我們首先來了解一下上述三個控件的共同特性。SelectionList和List控件允許開發人員定義靜態地定義各個列表項,也就是我們可以在服務器控件語法中使用<Item>標簽,來定義每個列表項對應的文本信息和值信息,而動態的實現方式就是通過代碼,創建和列表中的每個列表項對應的System.Web.UI.MobileControls.MobileListItem 對象,并將這些對象添加到列表控件的Items集合中。由于每個列表項都是預先設置好的,所有我們也稱這種列表為靜態列表。
還有一種方式就是將列表控件與一個數據源進行綁定,由于該列表控件中的所有列表項所需的文本信息和值信息都讀取自數據源,因此這些列表項都是根據這些信息動態生成。注意,上述的三個列表控件都支持數據綁定的方式動態地生成列表。
靜態列表的實現
前文提過,我們可以通過靜態的方式實現列表。其實這種實現就是在服務器控件語法中使用<Item>標簽來設置每個列表項所需的文本信息和值信息。下面我們來通過一段代碼來說明如何靜態地實現一個列表。程序清單1是一個SelectionList控件的聲明,我們希望通過該列表控件來選擇一個列表項。在這里我們將手機的品牌和型號分別作為列表項的文本信息和值信息,你可以在每個<Item>標簽中使用Text屬性自動文本信息,使用Value屬性指定值信息。
程序清單1:
我們將在"SelectionList列表控件詳解"這一章中通過具體的實例來應用程序清單1中的代碼,在這只是簡要地介紹下實現靜態列表的方法。其實我們還可以以一種可視化的方式來實現靜態列表,當然這要依靠Visual Studio 2005開發環境的支持。在Visual Studio 2005中,提供了一個非常有用的屬性生成器,使得你可以很方便地定義一個靜態列表。只要你選擇列表控件的智能標簽,而后再選擇"屬性生成器"鏈接,就會彈出"屬性生成器"對話框。我們可以通過該對話框以可視化的方式產生程序清單1中的代碼,如圖6所示。
圖6 我們可以在該對話框中通過"創建新項"按鈕來產生一個新的列表項,而后在這個列表項對應的"項文本"和"值"文本框處填寫好列表項的文本信息和值信息,就創建好了一個列表項。如果你要調整各個列表項之間的次序,可以點擊上下箭頭按鈕來做出相應的調整。 在"屬性生成器"對話框的"常規"選項卡中,用戶可以選擇列表控件在頁面上的呈現形式。例如SelectionList列表控件支持下拉列表、列表框、單項按鈕、復選按鈕和多選列表框等幾種形式,開發人員可以根據實際的需要選擇合適的類型,如圖7所示。
ASP.NET運行時是通過下面所描述的方式來解析服務器控件語法中的各個列表項的。在你使用靜態的方式構建一個列表時,ASP.NET實際上是針對這個列表中的每個列表項,都創建一個System.Mobile.UI.MobileControls.MobileListItem對象,并使用<Item> 標簽中的Text和Value屬性指定的文本信息和值信息對相應的MobileListItem對象進行初始化,而后再將初始化后的MobileListItem對象添加到一個System.Mobile.UI.MobileControls.MobileListItemCollection集合對象中。我們可以在代碼中通過SelectionList或List類的Items屬性來訪問這個MobileListItemCollection集合對象。事實上,程序清單1和程序清單2的功能是相同的,兩種方式都可以生成靜態列表,只不過程序清單1隱藏了靜態列表的底層的實現,更容易操作罷了。
程序清單2
將列表控件與數據集合進行綁定
前文提過,除了使用靜態的方式定義列表外,我們還可以將SelectionList 、List和ObjectList三個列表控件與特定的數據源進行綁定。這些列表控件支持兩種類型的數據源: System.Collections.IEnumerable和System.ComponentModel.IListSource。.Net Framework中的許多集合類都是實現了IEnumerator接口,為此這些類都支持簡單的枚舉功能。至于這些類的具體實例有位于System.Collections命名空間的Array、ArrayList、Hashtable和ListDictionary,還要一些和控件相關聯的集合對象(例如前面的代碼中使用到的MobileListItemCollection)。如果你要查看所有實現了IEnumerator接口的集合類的話,請自行參考MSDN幫助文檔。
你還可以將列表控件與IListSource數據集合進行綁定。System.Data命名空間中的兩個類實現了IListSource這種接口,這兩個類就是我們在ADO.NET中經常使用的DataSet和DataTable。我們知道這兩個類是相關聯的,因為DataSet相當于一個由多個DataTable組成的集合。DataSet類是ADO.NET構架中的一個主要組件,并且DataSet還相當于在數據庫中所檢索到的數據在內存中的一個緩存。當列表控件的數據源為一個DataSet對象時,因為一個DataSet可能包含多個DataTable對象,所以我們還必須使用SelectionList.DataMember屬性確切地指定使用那個DataTable對象來填充列表項。注意,當你使用一個IEnumerator數據源時,是沒有必要指定DataMember屬性的。至于DataSet在ASP.NET移動程序中的具體應用,將在其它章節中進行介紹。
當你需要以數據綁定的方式動態地實現一個列表的話,那么應該將該列表控件的DataSource屬性指定一個相關聯的數據源。如果數據源是一個DataSet對象的話,那么還需要使用DataMember屬性確切地指定用那個DataTable填充列表項。對于SelectionList和List控件來說,你可以使用DataTextField和DataValueField兩個屬性分別指定數據源中的兩個字段,列表控件會自動將這兩個字段的內容作為各個列表項的文本信息和值信息。而ObjectList列表控件是使用LabelField屬性來指定數據源中的一個字段,使得該字段中的內容應用到各個列表項中進行呈現,至于每個列表項的其它字段內容,你可以在ObjectList的詳細信息視圖頁上進行查看。
我們可以以代碼的方式或服務器控件語法的方式實現上述數據綁定屬性的設置。例如,你希望在一個SelectionList列表控件中使用Manufacturer字段作為各列表項的文本信息,且Model字段作為各列表項的值信息。那么其設置的方法如程序清單3所示:
程序清單3
為了獲取數據源中對應字段的內容,我們還需要定義一個類,使得每個列表項都可以讀取相應的文本信息和值信息。
程序清單4
然后,在Page_Load事件處理函數中,創建所有的數據項并將其添加到一個ArrayList對象中。最后就是設置列表控件的DataSource屬性了,在這里我們將DataSource指定為這個ArrayList對象。完成上述的步驟再調用DataBind方法,這樣就將列表控件和數據源進行綁定了。
程序清單4
使用上述代碼的完整示例將在具體探討每個列表控件時會應用到。
提示:DataBind方法對于數據綁定來說是至關重要的,很多開發人員經常忘記調用這個方法,以致列表控件不顯示任何列表項。我們可以使用兩種方法來使用DataBind方法,一種就是在每個要進行數據綁定的列表控件上單獨使用DataBind方法,如程序清單4所示。你還可以采用一種一勞永逸的方法,那就是使用MobilePage.DataBind方法(在程序清單4中,使用this.DataBind()替代 SelectionList1.DataBind(),這里的this代表的就是MobilePage)。這樣在頁面上存在多個數據綁定的列表控件時,僅需使用一個this.DataBind()方法就可以實現所有列表控件和數據源的綁定,而無需為每個實現了數據綁定的列表控件都調用一次DataBind方法。
概述
在很多情況下,我們都會使用到列表控件來方便用戶選擇一些選項。例如在某網站上注冊新用戶時,通常會詢問你的性別是"男"還是"女",這時我們用單項按鈕以供用戶做出相應的選擇。還有當你填寫自己的家庭地址時,通常會使用到一個包含各省省名的下拉列表來供用戶直接選擇,這樣可以減少用戶的輸入量。上述的這些單項按鈕和下拉列表都在ASP.NET移動程序中都是以列表控件的形式存在的。我們可以使用列表控件來呈現各種形式(單項、多選、下拉列表)的列表,以供用戶選擇和使用。但是在ASP.NET 2.0移動開發工具包中,只有三個列表控件,分別為SelectionList 、List和ObjectList 控件。雖然沒有ASP.NET 2.0中那么多類型的列表控件,但是我們卻可以使用SelectionList 、List和ObjectList這三個列表控件實現單項、多選等幾乎所有的功能。在本系列文章中將探討這三個控件的一些基本功能和使用方法,并說明這三個控件相似之處及異同點。
圖1是SelectionList 、List和ObjectList三個控件在類的繼承上的關系:
![]() 圖1 |
上面的三個列表控件中,SelectionList是最簡單的,但是它可以以各種不同的類型進行呈現,因此具有很大的靈活度,以供不同的需求使用應用的列表類型。同時因為SelectionList控件不支持分頁功能,所以在包含多個列表項的情況下,該控件就顯得力不從心了。還有一點要需要重點說明的是,SelectionList是這三個列表控件中唯一支持多選的。而且該控件還可以以下拉列表的形式進行呈現,也可以以單項和多選框的方式進行呈現,當然這種呈現格式必須要被移動設備上的瀏覽器所接受。在一些WML瀏覽器上,只支持一些特殊的呈現形式,例如單項和多選按鈕,并不支持下拉列表這種呈現形式。圖2演示了下拉列表在不同瀏覽器上呈現時所存在的差別。
![]() ![]() 圖2 在上圖所示的PocketIE瀏覽器上,列表控件是以下拉列表的形式呈現的。而在Openwave的WML瀏覽器上,下拉列表類型的呈現形式是不支持的,為此在該瀏覽器中,是將列表中的各個列表項顯示出來,供用戶進行相應的選擇。 |
List列表控件支持分頁功能,這就意味著它支持列表項較多的列表。它只可以以項目符號列表或編號列表的形式進行呈現(只要瀏覽器支持即可)。除了之外,其它的被SelectionList支持的列表形式(例如下拉列表),在List中均無法實現。圖3中List列表控件就是以編號列表的形式呈現的,并且支持分頁功能。
![]() 圖3 List列表控件以編號列表的形式呈現在頁面上,而且支持分頁功能。 |
在上述三個列表控件中最復雜的當屬ObjectList 控件了。SelectionList和List控件允許你使用服務器控件語法靜態地聲明列表項,但是ObjectList控件是無法采用這種方式來添加列表項的,你必須在ObjectLis列表控件與相應的數據源綁定后,再通過代碼將列表項添加到列表中。ObjectList 控件允許一個列表項中同時顯示多個字段,這是其它兩個控件所不具備的,它們只允許每個列表項只顯示一個字段的信息。除此之外,ObjectList 控件中的每個列表項還可以和多個命令相關聯,其它兩個控件所不具備的功能。
![]() 圖4 ObjectList 控件中,可以在每個列表項中顯示多個字段。這里同時顯示了球隊名稱、輸、贏和積分等字段。 ![]() 圖5 每個列表項可以和多個命令進行關聯,頁面下方的各個鏈接就是與列表項關聯的命令,你可以選擇不同的命令,產生不同的操作 |
下表概括了上述三個控件的主要功能:
| 能力 | SelectionList | List | ObjectList |
| 是否可以以下拉列表、列表框、 單項或多選按鈕等類型在HTML瀏覽器上進行呈現 | √ | ||
| 是否支持多選 | √ | ||
| 以項目符號列表或編號列表的形式進行呈現 | √ | ||
| 當列表包含較多的列表項時,是否可以啟用分頁功能 | √ | √ | |
| 是否可以通過服務器語法聲明靜態地生成列表項 | √ | √ | |
| 是否可以與數據源綁定 | √ | √ | √ |
| 在一個列表項中是否可以同時顯示多個字段 | √ | ||
| 在選擇一個列表項后是否會觸發相應的事件 | √(注釋) | √ | √ |
| 每個列表項是否可以自定義相關聯的命令 | √ | ||
| 是否支持模板 | √ | √ | |
| 注釋:SelectionList列表控件在選擇一個列表項后,其自身是無法自動產生一個回發(postback)操作的。你必須在包含該SelectionList列表控件的Form控件上放置一個Command控件,再由該Command控件將因列表選項發生改變的信息回發到服務器上,這樣ASP.NET運行時就可以根據這些信息做出相應的處理,并將處理后的信息返回到移動頁面上。 | |||
采用不同的方式構建列表
在開始探究每個列表控件的具體用法時,我們首先來了解一下上述三個控件的共同特性。SelectionList和List控件允許開發人員定義靜態地定義各個列表項,也就是我們可以在服務器控件語法中使用<Item>標簽,來定義每個列表項對應的文本信息和值信息,而動態的實現方式就是通過代碼,創建和列表中的每個列表項對應的System.Web.UI.MobileControls.MobileListItem 對象,并將這些對象添加到列表控件的Items集合中。由于每個列表項都是預先設置好的,所有我們也稱這種列表為靜態列表。
還有一種方式就是將列表控件與一個數據源進行綁定,由于該列表控件中的所有列表項所需的文本信息和值信息都讀取自數據源,因此這些列表項都是根據這些信息動態生成。注意,上述的三個列表控件都支持數據綁定的方式動態地生成列表。
靜態列表的實現
前文提過,我們可以通過靜態的方式實現列表。其實這種實現就是在服務器控件語法中使用<Item>標簽來設置每個列表項所需的文本信息和值信息。下面我們來通過一段代碼來說明如何靜態地實現一個列表。程序清單1是一個SelectionList控件的聲明,我們希望通過該列表控件來選擇一個列表項。在這里我們將手機的品牌和型號分別作為列表項的文本信息和值信息,你可以在每個<Item>標簽中使用Text屬性自動文本信息,使用Value屬性指定值信息。
程序清單1:
| <mobile:SelectionList id="SelectionList1" runat="server"> <Item Text="Dopoda" Value="P800" /> <Item Text="Motorola" Value="A1200" /> <Item Text="Nokia" Value="N70" /> <Item Text="Samsung" Value="E638" /> </mobile:SelectionList> |
我們將在"SelectionList列表控件詳解"這一章中通過具體的實例來應用程序清單1中的代碼,在這只是簡要地介紹下實現靜態列表的方法。其實我們還可以以一種可視化的方式來實現靜態列表,當然這要依靠Visual Studio 2005開發環境的支持。在Visual Studio 2005中,提供了一個非常有用的屬性生成器,使得你可以很方便地定義一個靜態列表。只要你選擇列表控件的智能標簽,而后再選擇"屬性生成器"鏈接,就會彈出"屬性生成器"對話框。我們可以通過該對話框以可視化的方式產生程序清單1中的代碼,如圖6所示。
![]() |
圖6 我們可以在該對話框中通過"創建新項"按鈕來產生一個新的列表項,而后在這個列表項對應的"項文本"和"值"文本框處填寫好列表項的文本信息和值信息,就創建好了一個列表項。如果你要調整各個列表項之間的次序,可以點擊上下箭頭按鈕來做出相應的調整。 在"屬性生成器"對話框的"常規"選項卡中,用戶可以選擇列表控件在頁面上的呈現形式。例如SelectionList列表控件支持下拉列表、列表框、單項按鈕、復選按鈕和多選列表框等幾種形式,開發人員可以根據實際的需要選擇合適的類型,如圖7所示。
![]() |
ASP.NET運行時是通過下面所描述的方式來解析服務器控件語法中的各個列表項的。在你使用靜態的方式構建一個列表時,ASP.NET實際上是針對這個列表中的每個列表項,都創建一個System.Mobile.UI.MobileControls.MobileListItem對象,并使用<Item> 標簽中的Text和Value屬性指定的文本信息和值信息對相應的MobileListItem對象進行初始化,而后再將初始化后的MobileListItem對象添加到一個System.Mobile.UI.MobileControls.MobileListItemCollection集合對象中。我們可以在代碼中通過SelectionList或List類的Items屬性來訪問這個MobileListItemCollection集合對象。事實上,程序清單1和程序清單2的功能是相同的,兩種方式都可以生成靜態列表,只不過程序清單1隱藏了靜態列表的底層的實現,更容易操作罷了。
程序清單2
| protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { SelectionList1.Items.Add(new MobileListItem("Dopoda", "P800")); SelectionList1.Items.Add(new MobileListItem("Motorola", "A1200")); SelectionList1.Items.Add(new MobileListItem("Nokia", "N70")); SelectionList1.Items.Add(new MobileListItem("Samsung", "E638")); } } |
將列表控件與數據集合進行綁定
前文提過,除了使用靜態的方式定義列表外,我們還可以將SelectionList 、List和ObjectList三個列表控件與特定的數據源進行綁定。這些列表控件支持兩種類型的數據源: System.Collections.IEnumerable和System.ComponentModel.IListSource。.Net Framework中的許多集合類都是實現了IEnumerator接口,為此這些類都支持簡單的枚舉功能。至于這些類的具體實例有位于System.Collections命名空間的Array、ArrayList、Hashtable和ListDictionary,還要一些和控件相關聯的集合對象(例如前面的代碼中使用到的MobileListItemCollection)。如果你要查看所有實現了IEnumerator接口的集合類的話,請自行參考MSDN幫助文檔。
你還可以將列表控件與IListSource數據集合進行綁定。System.Data命名空間中的兩個類實現了IListSource這種接口,這兩個類就是我們在ADO.NET中經常使用的DataSet和DataTable。我們知道這兩個類是相關聯的,因為DataSet相當于一個由多個DataTable組成的集合。DataSet類是ADO.NET構架中的一個主要組件,并且DataSet還相當于在數據庫中所檢索到的數據在內存中的一個緩存。當列表控件的數據源為一個DataSet對象時,因為一個DataSet可能包含多個DataTable對象,所以我們還必須使用SelectionList.DataMember屬性確切地指定使用那個DataTable對象來填充列表項。注意,當你使用一個IEnumerator數據源時,是沒有必要指定DataMember屬性的。至于DataSet在ASP.NET移動程序中的具體應用,將在其它章節中進行介紹。
當你需要以數據綁定的方式動態地實現一個列表的話,那么應該將該列表控件的DataSource屬性指定一個相關聯的數據源。如果數據源是一個DataSet對象的話,那么還需要使用DataMember屬性確切地指定用那個DataTable填充列表項。對于SelectionList和List控件來說,你可以使用DataTextField和DataValueField兩個屬性分別指定數據源中的兩個字段,列表控件會自動將這兩個字段的內容作為各個列表項的文本信息和值信息。而ObjectList列表控件是使用LabelField屬性來指定數據源中的一個字段,使得該字段中的內容應用到各個列表項中進行呈現,至于每個列表項的其它字段內容,你可以在ObjectList的詳細信息視圖頁上進行查看。
我們可以以代碼的方式或服務器控件語法的方式實現上述數據綁定屬性的設置。例如,你希望在一個SelectionList列表控件中使用Manufacturer字段作為各列表項的文本信息,且Model字段作為各列表項的值信息。那么其設置的方法如程序清單3所示:
程序清單3
| <mobile:SelectionList ID="SelectionList1" Runat="server" SelectType="MultiSelectListBox" DataTextField="Manufacturer" DataValueField="Model"> </mobile:SelectionList> |
為了獲取數據源中對應字段的內容,我們還需要定義一個類,使得每個列表項都可以讀取相應的文本信息和值信息。
程序清單4
| public class MobileTelephone { private String manufacturer, model; public MobileTelephone(String manufacturer, String model) { this.manufacturer = manufacturer; this.model = model; } public String Manufacturer { get { return this.manufacturer; } } public String Model { get { return this.model; } } } |
然后,在Page_Load事件處理函數中,創建所有的數據項并將其添加到一個ArrayList對象中。最后就是設置列表控件的DataSource屬性了,在這里我們將DataSource指定為這個ArrayList對象。完成上述的步驟再調用DataBind方法,這樣就將列表控件和數據源進行綁定了。
程序清單4
| protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { ArrayList array = new ArrayList(); array.Add(new MobileTelephone("Dopoda", "P800")); array.Add(new MobileTelephone("Motorola", "A1200")); array.Add(new MobileTelephone("Nokia", "N70")); array.Add(new MobileTelephone("Samsung", "E638")); SelectionList1.DataSource = array; SelectionList1.DataBind(); } } |
使用上述代碼的完整示例將在具體探討每個列表控件時會應用到。
提示:DataBind方法對于數據綁定來說是至關重要的,很多開發人員經常忘記調用這個方法,以致列表控件不顯示任何列表項。我們可以使用兩種方法來使用DataBind方法,一種就是在每個要進行數據綁定的列表控件上單獨使用DataBind方法,如程序清單4所示。你還可以采用一種一勞永逸的方法,那就是使用MobilePage.DataBind方法(在程序清單4中,使用this.DataBind()替代 SelectionList1.DataBind(),這里的this代表的就是MobilePage)。這樣在頁面上存在多個數據綁定的列表控件時,僅需使用一個this.DataBind()方法就可以實現所有列表控件和數據源的綁定,而無需為每個實現了數據綁定的列表控件都調用一次DataBind方法。







