Używanie kontrolki CascadingDropDown z bazą danych (VB)
Autor: Christian Wenz
Kontrolka CascadingDropDown w zestawie narzędzi AJAX Control Toolkit rozszerza kontrolkę DropDownList, aby zmiany w jednej kontrolce DropDownList ładowały skojarzone wartości w innej kontrolce DropDownList. Aby to zadziałało, należy utworzyć specjalną usługę internetową.
Omówienie
Kontrolka CascadingDropDown w zestawie narzędzi AJAX Control Toolkit rozszerza kontrolkę DropDownList, aby zmiany w jednej kontrolce DropDownList ładowały skojarzone wartości w innej kontrolce DropDownList. (Na przykład jedna lista zawiera listę stanów USA, a następna lista jest następnie wypełniona dużymi miastami w tym stanie). Aby to zadziałało, należy utworzyć specjalną usługę internetową.
Kroki
Przede wszystkim wymagane jest źródło danych. W tym przykładzie użyto bazy danych AdventureWorks i SQL Server 2005 Express Edition firmy Microsoft. Baza danych jest opcjonalną częścią instalacji programu Visual Studio (w tym wersji ekspresowej) i jest również dostępna jako oddzielny plik do pobrania w obszarze https://go.microsoft.com/fwlink/?LinkId=64064. Baza danych AdventureWorks jest częścią przykładów i przykładowych baz danych SQL Server 2005 (pobierz na stronie https://www.microsoft.com/download/details.aspx?id=10679). Najprostszym sposobem skonfigurowania bazy danych jest użycie programu Microsoft SQL Server Management Studio (/sql/ssms/download-sql-server-management-studio-ssms) i dołączenie AdventureWorks.mdf
pliku bazy danych.
W tym przykładzie przyjęto założenie, że wystąpienie SQL Server 2005 Express Edition jest wywoływane SQLEXPRESS
i znajduje się na tej samej maszynie co serwer internetowy. Jest to również konfiguracja domyślna. Jeśli konfiguracja jest inna, musisz dostosować informacje o połączeniu dla bazy danych.
Aby aktywować funkcje ASP.NET AJAX i Control Toolkit, kontrolka ScriptManager
musi zostać umieszczona w dowolnym miejscu na stronie (ale w elemecieform
<>):
<asp:ScriptManager ID="asm" runat="server" />
W następnym kroku wymagane są dwie kontrolki DropDownList. W tym przykładzie używamy informacji kontaktowych i dostawcy z firmy AdventureWorks, dlatego tworzymy jedną listę dla dostępnych dostawców i jedną dla dostępnych kontaktów:
<div>
Vendor: <asp:DropDownList ID="VendorsList" runat="server"/><br />
Contacts: <asp:DropDownList ID="ContactsList" runat="server"/><br />
</div>
Następnie do strony należy dodać dwa rozszerzenia CascadingDropDown. Jedna wypełnia pierwszą (dostawcy) listę, a druga wypełnia drugą (kontakty). Należy ustawić następujące atrybuty:
ServicePath
: adres URL usługi internetowej dostarczającej wpisy listyServiceMethod
: Metoda sieci Web dostarczająca wpisy listyTargetControlID
: identyfikator listy rozwijanejCategory
: informacje o kategorii przesyłane do metody sieci Web po wywołaniuPromptText
: tekst wyświetlany podczas asynchronicznego ładowania danych listy z serweraParentControlID
: (opcjonalnie) nadrzędna lista rozwijana, która wyzwala ładowanie bieżącej listy
W zależności od używanego języka programowania nazwa danej usługi internetowej zmienia się, ale wszystkie inne wartości atrybutów są takie same. Oto element CascadingDropDown dla pierwszej listy rozwijanej:
<ajaxToolkit:CascadingDropDown ID="ccd1" runat="server"
ServicePath="CascadingDropdown1.vb.asmx" ServiceMethod="GetVendors"
TargetControlID="VendorsList" Category="Vendor"
PromptText="Select Vendor" />
Rozszerzenia kontrolek dla drugiej listy muszą ustawić ParentControlID
atrybut, aby wybranie wpisu na liście dostawców wyzwalało ładowanie skojarzonych elementów na liście kontaktów.
<ajaxToolkit:CascadingDropDown ID="ccd2" runat="server"
ServicePath="CascadingDropdown1.vb.asmx" ServiceMethod="GetContactsForVendor"
TargetControlID="ContactsList" ParentControlID="VendorsList"
Category="Contact"
PromptText="Select Contact" />
Rzeczywista praca jest następnie wykonywana w usłudze internetowej, która jest skonfigurowana w następujący sposób. Należy pamiętać, że [ScriptService]
atrybut jest używany, w przeciwnym razie ASP.NET AJAX nie może utworzyć serwera proxy JavaScript w celu uzyskania dostępu do metod internetowych z kodu skryptu po stronie klienta.
<%@ 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
Podpis metod internetowych wywoływanych przez metodę CascadingDropDown jest następujący:
Public Function MethodNameHere(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
Dlatego wartość zwracana musi być tablicą typu CascadingDropDownNameValue
, która jest definiowana przez zestaw narzędzi Control Toolkit. Metoda GetVendors()
jest dość łatwa do zaimplementowania: kod łączy się z bazą danych AdventureWorks i wysyła zapytanie do pierwszych 25 dostawców. Pierwszy parametr w konstruktorze CascadingDropDownNameValue
jest podpis wpisu listy, drugi jego wartość (atrybut value w elemecie HTMLoption
<>). Oto kod:
<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
Pobieranie skojarzonych kontaktów dla dostawcy (nazwa metody: GetContactsForVendor()
) jest nieco trudniejsze. Najpierw należy określić dostawcę, który został wybrany na pierwszej liście rozwijanej. Zestaw narzędzi Control Toolkit definiuje metodę pomocnika dla tego zadania: ParseKnownCategoryValuesString()
Metoda zwraca StringDictionary
element z danymi listy rozwijanej:
<WebMethod()> _
Public Function GetContactsForVendor(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
Dim VendorID As Integer
CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)
Ze względów bezpieczeństwa te dane muszą zostać najpierw zweryfikowane. Jeśli więc istnieje wpis Dostawca (ponieważ Category
właściwość pierwszego elementu CascadingDropDown jest ustawiona na "Vendor"
), identyfikator wybranego dostawcy może zostać pobrany:
If Not kv.ContainsKey("Vendor") Or Not Int32.TryParse(kv("Vendor"),VendorID) Then
Throw New ArgumentException("Couldn't find vendor.")
End If
Reszta metody jest dość prosta, a następnie. Identyfikator dostawcy jest używany jako parametr zapytania SQL, który pobiera wszystkie skojarzone kontakty dla tego dostawcy. Po raz kolejny metoda zwraca tablicę typu 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
Załaduj stronę ASP.NET, a po chwili lista dostawców zostanie wypełniona 25 wpisami. Wybierz jeden wpis i zwróć uwagę, jak druga lista rozwijana jest wypełniona danymi.
Pierwsza lista jest wypełniana automatycznie (kliknij, aby wyświetlić obraz pełnowymiarowy)
Druga lista jest wypełniona zgodnie z zaznaczeniem na pierwszej liście (kliknij, aby wyświetlić obraz pełnowymiarowy)