作者 :克里斯蒂安·溫茲
AJAX 控制工具包中的 CascadingDropDown 控制項是用來擴充 DropDownList 控制項的,其功能是當一個下拉清單發生變更時,可載入另一個下拉清單的相關值。 為了讓這一切運作,必須建立一個特殊的網路服務。
概觀
AJAX 控制工具包中的 CascadingDropDown 控制項是用來擴充 DropDownList 控制項的,其功能是當一個下拉清單發生變更時,可載入另一個下拉清單的相關值。 (例如,一個清單提供美國各州的清單,下一個清單則填入該州的主要城市。)為了讓這一切運作,必須建立一個特殊的網路服務。
Steps
首先,需要一個資料來源。 此範例使用 AdventureWorks 資料庫及 Microsoft SQL Server 2005 Express Edition。 該資料庫是 Visual Studio 安裝(包括 Express 版)的選用部分,也可以在https://go.microsoft.com/fwlink/?LinkId=64064單獨下載。 AdventureWorks 資料庫是 SQL Server 2005 範例與範例資料庫的一部分(可於 https://www.microsoft.com/download/details.aspx?id=10679此下載)。 設定資料庫最簡單的方法是使用 Microsoft SQL Server Management Studio(/sql/ssms/download-sql-server-management-studio-ssms)並附加 AdventureWorks.mdf 資料庫檔案。
在此範例中,我們假設 SQL Server 2005 Express Edition 的實例被呼叫 SQLEXPRESS 並駐留於與網頁伺服器同一台機器上;這也是預設設定。 如果你的設定不同,你必須調整資料庫的連線資訊。
為了啟用 ASP.NET AJAX 及控制工具包的功能, ScriptManager 控制項必須放置在頁面上的任何位置(但不在元素 <form> 內):
<asp:ScriptManager ID="asm" runat="server" />
下一步則需要兩個下拉清單控制項。 在這個範例中,我們使用 AdventureWorks 的供應商和聯絡資訊,因此我們建立了一份可用供應商清單,另一份清單列出可用聯絡人:
<div>
Vendor: <asp:DropDownList ID="VendorsList" runat="server"/><br />
Contacts: <asp:DropDownList ID="ContactsList" runat="server"/><br />
</div>
接著,必須在頁面上新增兩個 CascadingDropDown 擴展器。 一個負責第一個(供應商)清單,另一個負責第二個(聯絡人)清單。 必須設定以下屬性:
-
ServicePath: 提供清單條目的網路服務的網址 -
ServiceMethod:網路方法提供列表項目 -
TargetControlID: 下拉選單的識別碼 -
Category: 當呼叫時提交給 Web 方法的分類資訊 -
PromptText:非同步載入列表資料時顯示的文字 -
ParentControlID:(可選性)觸發載入當前清單的父下拉選單
根據所使用的程式語言,相關網路服務的名稱會有所不同,但其他屬性值則相同。 這是第一個下拉選單的 CascadingDropDown 元素:
<ajaxToolkit:CascadingDropDown ID="ccd1" runat="server"
ServicePath="CascadingDropdown1.vb.asmx" ServiceMethod="GetVendors"
TargetControlID="VendorsList" Category="Vendor"
PromptText="Select Vendor" />
第二個清單的控制延伸器需要設定屬性 ParentControlID ,使得在供應商清單中選擇條目時,會觸發在聯絡人清單中載入相關元素。
<ajaxToolkit:CascadingDropDown ID="ccd2" runat="server"
ServicePath="CascadingDropdown1.vb.asmx" ServiceMethod="GetContactsForVendor"
TargetControlID="ContactsList" ParentControlID="VendorsList"
Category="Contact"
PromptText="Select Contact" />
實際工作則在網路服務中完成,設定如下。 請注意 [ScriptService] ,屬性已被使用,否則 ASP.NET AJAX 無法建立 JavaScript 代理,無法從客戶端腳本程式碼存取網頁方法。
<%@ WebService Language="VB" Class="CascadingDropdown1" %>
Imports System.Web.Script.Services
Imports AjaxControlToolkit
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Collections.Generic
Imports System.Collections.Specialized
Imports System.Data.SqlClient
<ScriptService()> _
Public Class CascadingDropdown1
Inherits System.Web.Services.WebService
' ...
End Class
CascadingDropDown 所呼叫的網頁方法簽名如下:
Public Function MethodNameHere(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
因此回傳值必須是控制工具包所定義的CascadingDropDownNameValue類型的陣列。 此 GetVendors() 方法相當容易實作:程式碼連接 AdventureWorks 資料庫並查詢前 25 家廠商。 建構子中的 CascadingDropDownNameValue 第一個參數是列表條目的說明文字,第二個參數是它的值(HTML 元素中的 <option> value 屬性)。 程式碼如下:
<WebMethod()> _
Public Function GetVendors(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
Dim conn As New SqlConnection("server=(local)\SQLEXPRESS; Integrated Security=true; Initial Catalog=AdventureWorks")
conn.Open()
Dim comm As New SqlCommand( _
"SELECT TOP 25 VendorID, Name FROM Purchasing.Vendor", conn)
Dim dr As SqlDataReader = comm.ExecuteReader()
Dim l As New List(Of CascadingDropDownNameValue)
While (dr.Read())
l.Add(New CascadingDropDownNameValue(dr("Name").ToString(),dr("VendorID").ToString()))
End While
conn.Close()
Return l.ToArray()
End Function
取得供應商(方法名稱: GetContactsForVendor())的相關聯絡方式就比較棘手。 首先,必須確定第一個下拉選單中已選擇的供應商。 控制工具包為該任務定義了一個輔助方法:ParseKnownCategoryValuesString() 方法會回傳一個包含下拉選單資料的 StringDictionary 元素。
<WebMethod()> _
Public Function GetContactsForVendor(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
Dim VendorID As Integer
CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)
出於安全考量,這些資料必須先進行驗證。 因此,如果有供應商條目(因為 Category 第一個 CascadingDropDown 元素的屬性設定為 "Vendor"),就可以取得所選供應商的 ID:
If Not kv.ContainsKey("Vendor") Or Not Int32.TryParse(kv("Vendor"),VendorID) Then
Throw New ArgumentException("Couldn't find vendor.")
End If
其餘的方法相當直接。 供應商的 ID 作為 SQL 查詢的參數,該查詢會取得該供應商所有相關的聯絡人。 同樣地,該方法回傳一個型別 CascadingDropDownNameValue為 的陣列。
Dim conn As New SqlConnection("server=(local)\SQLEXPRESS; Integrated Security=true; Initial Catalog=AdventureWorks")
conn.Open()
Dim comm As New SqlCommand("SELECT Person.Contact.ContactID, FirstName, LastName FROM Person.Contact,Purchasing.VendorContact WHERE VendorID=@VendorID AND Person.Contact.ContactID=Purchasing.VendorContact.ContactID",conn)
comm.Parameters.AddWithValue("@VendorID", VendorID)
Dim dr As SqlDataReader = comm.ExecuteReader()
Dim l As New List(Of CascadingDropDownNameValue)
While (dr.Read())
l.Add(New CascadingDropDownNameValue(dr("FirstName").ToString() & " " & dr("LastName").ToString(),dr("ContactID").ToString()))
End While
conn.Close()
Return l.ToArray()
End Function
載入 ASP.NET 頁面,不久後供應商名單會填滿25個條目。 選擇一個條目,注意第二個下拉選單被填滿了資料。
第一個清單會自動填滿(點擊查看全尺寸圖片)
第二個清單依據第一個列表中的選擇填滿(點擊查看全尺寸圖片)