データベースで CascadingDropDown を使用する (C#)
作成者: Christian Wenz
AJAX Control Toolkit の CascadingDropDown コントロールは、DropDownList コントロールを拡張して、ある DropDownList で変更が行われると、別の DropDownList にある関連付けられた値が読み込まれるようにします。 これを機能させるには、特別な Web サービスを作成する必要があります。
概要
AJAX Control Toolkit の CascadingDropDown コントロールは、DropDownList コントロールを拡張して、ある DropDownList で変更が行われると、別の DropDownList にある関連付けられた値が読み込まれるようにします。 (たとえば、あるリストに米国の州の一覧があり、次のリストにはその州の主要都市が入力されます。)これを機能させるには、特別な Web サービスを作成する必要があります。
手順
まず第一に、データ ソースが必要です。 このサンプルでは、AdventureWorks データベースと Microsoft SQL Server 2005 Express Edition を使用します。 このデータベースは、Visual Studio のインストール (Express Edition を含む) のオプションの部分であり、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
と呼ばれ、Web サーバーと同じマシン上に存在することを前提としています。これは既定のセットアップでもあります。 セットアップが異なる場合は、そのデータベースの接続情報を調整する必要があります。
ASP.NET AJAX の機能と Control Toolkit をアクティブにするには、ScriptManager
コントロールをページ上の任意の場所 (ただし <form
> 要素内) に配置する必要があります。
<asp:ScriptManager ID="asm" runat="server" />
次の手順では、2 つの DropDownList コントロールが必要です。 このサンプルでは、AdventureWorks のベンダーと連絡先情報を使用するため、使用可能なベンダー用に 1 つのリストと、使用可能な連絡先用に 1 つのリストを作成します。
<div>
Vendor: <asp:DropDownList ID="VendorsList" runat="server"/><br />
Contacts: <asp:DropDownList ID="ContactsList" runat="server"/><br />
</div>
次に、2 つの CascadingDropDown エクステンダー コントロールをページに追加する必要があります。 1 つは最初の (ベンダー) リストに入力し、もう 1 つは 2 番目の (連絡先) リストに入力します。 次の属性を設定する必要があります。
ServicePath
: 一覧のエントリを提供する Web サービスの URLServiceMethod
: 一覧のエントリを提供する Web メソッドTargetControlID
: ドロップダウン リストの IDCategory
: 呼び出されたら Web メソッドに送信されるカテゴリ情報PromptText
: サーバーから一覧のデータが非同期に読み込まれているときに表示されるテキストParentControlID
: (省略可能) 現在の一覧の読み込みをトリガーする親ドロップダウン リスト
使用するプログラミング言語に応じて、問題の Web サービスの名前は変わりますが、他のすべての属性値は同じです。 最初のドロップダウン リストの CascadingDropDown 要素を次に示します。
<ajaxToolkit:CascadingDropDown ID="ccd1" runat="server"
ServicePath="CascadingDropdown1.cs.asmx" ServiceMethod="GetVendors"
TargetControlID="VendorsList" Category="Vendor"
PromptText="Select Vendor" />
2 番目のリストのコントロール エクステンダーは、ベンダーリストでエントリを選択すると、連絡先リスト内の関連する要素の読み込みをトリガーするように、 ParentControlID
属性を設定する必要があります。
<ajaxToolkit:CascadingDropDown ID="ccd2" runat="server"
ServicePath="CascadingDropdown1.cs.asmx" ServiceMethod="GetContactsForVendor"
TargetControlID="ContactsList" ParentControlID="VendorsList"
Category="Contact"
PromptText="Select Contact" />
その後、実際の作業は、次のように設定された Web サービスで行われます。 [ScriptService]
属性が使用されていることに注意してください。それ以外の場合、ASP.NET AJAX では、クライアント側のスクリプト コードから Web メソッドにアクセスするための JavaScript プロキシを作成できません。
<%@ WebService Language="C#" Class="CascadingDropdown1" %>
using System.Web.Script.Services;
using AjaxControlToolkit;
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data.SqlClient;
[ScriptService]
public class CascadingDropdown1 : System.Web.Services.WebService
{
// ...
}
CascadingDropDown によって呼び出される Web メソッドのシグネチャは次のとおりです。
public CascadingDropDownNameValue[] MethodNameHere(string knownCategoryValues,
string category)
したがって、戻り値は、Control Toolkit によって定義された CascadingDropDownNameValue
型の配列である必要があります。 GetVendors()
メソッドは非常に簡単に実装できます。コードは AdventureWorks データベースに接続し、最初の 25 のベンダーに対してクエリを実行します。 CascadingDropDownNameValue
コンストラクターの最初のパラメーターは一覧のエントリのキャプションであり、2 番目のパラメーターはその値 (HTML の <option
> 要素の値属性) です。 次にコードを示します。
[WebMethod]
public CascadingDropDownNameValue[] GetVendors(string knownCategoryValues, string category)
{
SqlConnection conn = new SqlConnection("server=(local)\\SQLEXPRESS;
Integrated Security=true; Initial Catalog=AdventureWorks");
conn.Open();
SqlCommand comm = new SqlCommand("SELECT TOP 25 VendorID, Name
FROM Purchasing.Vendor",conn);
SqlDataReader dr = comm.ExecuteReader();
List<CascadingDropDownNameValue> l = new List<CascadingDropDownNameValue>();
while (dr.Read())
{
l.Add(new CascadingDropDownNameValue(dr["Name"].ToString(),
dr["VendorID"].ToString()));
}
conn.Close();
return l.ToArray();
}
ベンダーに関連付けられている連絡先 (メソッド名: GetContactsForVendor()
) を取得する方が少し複雑です。 まず、最初のドロップダウン リストで選択されたベンダーを決定する必要があります。 Control Toolkit は、そのタスクのヘルパー メソッドを定義します。ParseKnownCategoryValuesString()
メソッドは、ドロップダウン データを含む StringDictionary
要素を返します。
[WebMethod]
public CascadingDropDownNameValue[] GetContactsForVendor(string knownCategoryValues,
string category)
{
int VendorID;
CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);
セキュリティ上の理由から、このデータを最初に検証する必要があります。 したがって、Vendor エントリがある場合 (最初の CascadingDropDown 要素の Category
プロパティが "Vendor"
に設定されているため)、選択したベンダーの ID を取得できます。
if (!kv.ContainsKey("Vendor") || !Int32.TryParse(kv["Vendor"],out VendorID))
{
throw new ArgumentException("Couldn't find vendor.");
};
メソッドの残りの部分は非常に簡単です。 ベンダーの ID は、そのベンダーに関連付けられているすべての連絡先を取得する SQL クエリのパラメーターとして使用されます。 もう一度、このメソッドは CascadingDropDownNameValue
型の配列を返します。
SqlConnection conn = new SqlConnection("server=(local)\\SQLEXPRESS;
Integrated Security=true; Initial Catalog=AdventureWorks");
conn.Open();
SqlCommand comm = 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);
SqlDataReader dr = comm.ExecuteReader();
List<CascadingDropDownNameValue> l = new List<CascadingDropDownNameValue>();
while (dr.Read())
{
l.Add(new CascadingDropDownNameValue(
dr["FirstName"].ToString() + " " + dr["LastName"].ToString(),
dr["ContactID"].ToString()));
}
conn.Close();
return l.ToArray();
}
ASP.NET ページを読み込み、しばらくするとベンダーリストに 25 個のエントリが設定されます。 1 つのエントリを選択し、2 番目のドロップダウン リストにデータがどのように設定されているかを確認します。
最初の一覧が自動的に設定されます (クリックするとフルサイズの画像が表示されます)
2 番目の一覧は、最初の一覧の選択内容に従って設定されます (クリックするとフルサイズの画像が表示されます)