CasCadingDropDown

CasCadingDropDown

最近我需要有多層式(三層式)下拉的功能

本想利用最直接的方法,就是3個DropDownList+Update Panel防止他PostBack

可是利用了之後,我發現這3個DropDownList還是會一閃一閃

雖然此時不會PostBack,可是我看他一閃一閃的,實在很討厭咧=.=

因此這裡我轉向去利用CasCadingDropDown這個Ajax Extender

要利用CasCadingDropDown必須有3個前置作業

第一:使用用Web Service的方式去呼叫

第二:在Web Service的前面要先宣告

<System.Web.Script.Services.ScriptService()> _

第三:如果DropDownList有事件會觸發或是其它控制項的事件會影響DropDownList的話,要在Page的前置詞補上

<%@ Page EnableEventValidation="false" %>


有了上述三個前置作業,接下來就要開始實作,這邊我以VB的方式呈現

並以Northwind資料庫為例,根據Category的選擇,來呈現Product的內容

Step 1:

在畫面上我們拖曳ScriptManager、2個DropDownList(ddlCategory,ddlProduct)及1個CasCadingDropDown控制項,畫面會像如圖

ui

Step 2 :

接著我們去Page_Load事件預先載入Category的項目,完成後的畫面大概是呈現如下

 


Imports System.Data
Imports System.Data.SqlClient

Partial Class CasCading
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If (Not IsPostBack) Then
            BindData()
        End If
    End Sub

    Protected Sub BindData()
        Dim connString As String = System.Configuration.ConfigurationManager.AppSettings("Northwind_Connection").ToString()
        Dim conn As New SqlConnection(connString)
        conn.Open()

        Dim sql As String = "SELECT * FROM Categories"
        Dim dr As New SqlDataAdapter(sql, conn)
        Dim ds As New DataSet
        dr.Fill(ds)

        ddlCategory.DataSource = ds
        ddlCategory.DataTextField = "CategoryName"
        ddlCategory.DataValueField = "CategoryID"
        ddlCategory.DataBind()
    End Sub

End Class

 

Step 3 :

還記得我們剛才講的,要利用CasCadingDropDown的方式必須透過Webservice的方式

這邊我新增一支Webservce命名為CascadingDropDownlist

接著在最前面宣告

<System.Web.Script.Services.ScriptService()> _ 

最後我們就可以開始來撰寫我們的CasCadingDropDown的Webservice了

我宣告一個Function GetContents回傳CascadingDropDownNameValue的陣列

CascadingDropDownNameValue的陣列方法是AjaxControlToolkit裡面的

詳細的程式碼,大概會像以下的畫面


Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Data
Imports System.Data.SqlClient

' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
' <System.Web.Script.Services.ScriptService()> _
<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<System.Web.Script.Services.ScriptService()> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class CascadingDropDownlist
    Inherits System.Web.Services.WebService

    <WebMethod()> _
    Public Function HelloWorld() As String
        Return "Hello World"
    End Function

    <WebMethod()> _
    Public Function GetContents(ByVal knownCategoryValues As String, ByVal category As String) As AjaxControlToolkit.CascadingDropDownNameValue()
        Dim connString = System.Configuration.ConfigurationManager.AppSettings("Northwind_Connection").ToString()
        Dim conn As New SqlConnection(connString)
        conn.Open()

        'knownCategoryValues傳進來會以"undefined:DropdownList.id;"的方式進來
        '如我第一個DropDownList的id為1,則他會呈現"undefined:1;"
        '因此這邊我要抓出Dropdownlist的值,也就是index為1的
        Dim categoryValues() As String = knownCategoryValues.Split(":"c, ";"c)
        Dim categoryID As Integer = Convert.ToInt32(categoryValues(1))

        Dim ds As New DataSet
        Dim sql As String = "SELECT ProductID, ProductName from Products WHERE CategoryID='" + categoryID.ToString() + "'"
        Dim dap As New SqlDataAdapter(sql, conn)

        dap.Fill(ds)


        Dim itemCollection As List(Of AjaxControlToolkit.CascadingDropDownNameValue) = New List(Of AjaxControlToolkit.CascadingDropDownNameValue)


        For Each dr As DataRow In ds.Tables(0).Rows
            itemCollection.Add(New AjaxControlToolkit.CascadingDropDownNameValue(dr("ProductName"), dr("ProductID")))
        Next

        Return itemCollection.ToArray()

    End Function

End Class

最後我們回到Step 1,要設定的CasCadingDropDown屬性


<cc1:CascadingDropDown ID="CascadingDropDown1" runat="server" 
        ParentControlID="ddlCategory" TargetControlID="ddlProduct" ServicePath="CascadingDropDownlist.asmx"
        PromptText="Select the item" ServiceMethod="GetContents" Category="CategoryName">
        </cc1:CascadingDropDown>

其中,ServicePath表示Webservice的所在位置,而ServiceMethod表示我們Webservice的方法

詳細的屬性值,請點選CascadingDropDown

最後再提一下,我們的Webservice回傳是以CascadingDropDownNameValue陣列方式,

然而我們也可以以泛型來回傳,如果各位有興趣的話,可下載附件參考

 


 

 下載C#範例   下載VB範例