この記事では、ASP.NET AJAX フレームワークを使用してカスケード ドロップダウン リストを作成する方法について説明します。
元の製品バージョン: .NET Framework 3.5
元の KB 番号: 976156
はじめに
Note
ASP.NET AJAX 機能を使用するには、.NET Framework 3.5 がインストールされている必要があります。 ASP.NET AJAX 機能を .NET Framework 2.0 に組み込む場合は、ASP.NET 2.0 AJAX Extensions 1.0 がインストールされている必要があります。
カスケード ドロップダウン リストは、1 つのDropDownList
コントロールが親コントロールまたは以前のDropDownList
コントロールに依存する一連の依存DropDownList
コントロールです。 DropDownList
コントロール内の項目は、別のDropDownList
コントロールからユーザーが選択した項目に基づいて設定されます。 親 DropDownList
コントロールの選択が変更されると、Web ページは AJAX Web サービスを呼び出して、子 DropDownList
コントロールの値の一覧を取得します。 ASP.NET AJAX フレームワークを使用すると、クライアント スクリプトを使用してブラウザーから Web サービス (.asmx ファイル) を呼び出すことができます。 そのため、親DropDownList
コントロールのクライアント側のonchange
イベントで Web サービスを呼び出すと、Web ページは一部だけ更新され、子DropDownList
コントロールの項目が設定されます。
Note
ASP.NET AJAX コントロール ツールキットは、ASP.NET AJAX エクステンダーとして CascadingDropDown
コントロールを提供します。 CascadingDropDown
コントロールを使用して、カスケード ドロップダウン リストを作成できます。 この記事では、ASP.NET の標準 DropDownList
コントロールを ASP.NET AJAX フレームワークと共に使用してカスケード ドロップダウン関数を実現する方法について説明します。
カスケード ドロップダウン リストを作成する手順
Visual Studio で ASP.NET Web サービス アプリケーションを作成します。
Note
提供されているサンプル コードでは、C# サンプル プロジェクトのプロジェクト名が KB_CascadingDDL_CS。 Visual Basic .NET サンプル プロジェクトのプロジェクト名が KB_CascadingDDL_VB。
プロジェクトに AJAX Web フォームを追加します。
Note
サンプル コードでは、Web フォームのファイル名が Default.aspx。 AJAX Web サービス名は WebService です。
AJAX Web サービスの WebServiceName.asmx ファイルを開き、クラス宣言のコメント マークを次のように削除します。
Visual Basic
<System.Web.Script.Services.ScriptService()> Public Class WebService
Visual C#
[System.Web.Script.Services.ScriptService] public class WebService : System.Web.Services.WebService
Note
この手順により、クライアント側スクリプトから AJAX Web サービスにアクセスできるようになります。 AJAX Web サービス クラスには
ScriptServiceAttribute
属性が適用されている必要があり、クライアント側スクリプトから呼び出される個々のメソッドには、WebMethodAttribute
属性が適用されている必要があります。Web フォームの WebFormName.aspx ファイルを開き、次のように <asp:ScriptManager> タグを変更します。
<asp:ScriptManager ID="ScriptManager1" runat="server"> <Services> <asp:ServiceReference Path="~/WebServiceName.asmx" /> </Services> </asp:ScriptManager>
ASP.NET Web フォームのクライアント側スクリプトから AJAX Web サービスを呼び出せるようにするには、まず、
ScriptManager
コントロールを Web ページに追加する必要があります。 次に、<asp:ScriptManager>
タグに<asp:ServiceReference>
子要素を追加して、Web サービスを参照します。<asp:ScriptManager>
タグで、Path
属性を Web サービス ファイルを指すように設定します。ServiceReference
オブジェクトは、ASP.NET 2.0 AJAX 拡張機能に、Web ページのクライアント側スクリプトから指定された Web サービスを呼び出すための JavaScript プロキシ クラスを生成するように指示します。 プロキシ クラスには、AJAX Web サービスの各 Web サービス メソッドに対応するメソッドがあります。 Web ページには、Web サービス メソッドの入力パラメーターまたは戻り値として使用されるサーバー データ型に対応する JavaScript プロキシ クラスも含まれています。 これらのプロキシ クラスを使用すると、これらのパラメーターを初期化して Web サービス メソッド呼び出しに渡すクライアント側スクリプトを記述できます。次の例に示すように、WebFormName.aspx ファイルのソース コードで、Web ページの
EnableEventValidation
プロパティを false に設定します。<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="KB_CascadingDDL_VB._Default" EnableEventValidation="false" %>
Note
この手順では、Web サービス メソッド呼び出しを使用するときに無効なポストバックを回避します。
<asp:ScriptManager> タグの下に次のコードを追加して、必要な ASP.NET コントロールを生成します。
<table> <tr> <td> Make: </td> <td> <asp:DropDownList ID="ddlMake" Width="200" runat="server" AutoPostBack="false" onchange="ddl_changed(this)" /> </td> </tr> <tr> <td> Model: </td> <td> <asp:DropDownList ID="ddlModel" Width="200" runat="server" AutoPostBack="false" onchange="ddl_changed(this)" /> </td> </tr> <tr> <td> Color: </td> <td> <asp:DropDownList ID="ddlColor" Width="200" runat="server" AutoPostBack="false" onchange="DisplayResult()" /> </td> </tr> <tr> <td> <asp:Button ID="btnReset" runat="server" Text="Reset" /> </td> </tr> </table> <a id="aResult" />
AJAX Web サービスの Web サービス メソッドを作成します。 次のコードをコピーし、 WebServiceName.asmx ファイルに貼り付けます。
Visual Basic
Imports System.Web.Services Imports System.Web.Services.Protocols Imports System.ComponentModel ' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. <System.Web.Script.Services.ScriptService()> _ <System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _ <System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _ <ToolboxItem(False)> _ Public Class WebService Inherits System.Web.Services.WebService <WebMethod()> _ Public Function GetMakeValue() As String() Return New String() {"Please select", "Ford", "Dodge"} End Function <WebMethod()> _ Public Function GetChildValue(ByVal parentID As String, ByVal parentValue As String) As String() If parentValue = "Please select" Then Return Nothing End If Dim values As String() If parentID = "ddlMake" Then If parentValue = "Ford" Then values = New String() {"Please select", "Explorer", "F150", "Mustang"} ElseIf parentValue = "Dodge" Then values = New String() {"Please select", "Durango", "Dakota", "Viper"} Else Return New String() {"Invalid Make value!"} End If ElseIf parentID = "ddlModel" Then Select Case parentValue Case "Explorer", "Dakota", "Viper" values = New String() {"Please select", "Black", "Green", "Yellow"} Case "Durango", "F150", "Mustang" values = New String() {"Please select", "White", "Red", "Blue"} Case Else values = New String() {"Invalid Model value!"} End Select Else Return New String() {"Invalid Category value!"} End If Return values End Function End Class
Visual C#
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; namespace KB_CascadingDDL_CS { /// <summary> /// Summary description for WebService /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. [System.Web.Script.Services.ScriptService] public class WebService : System.Web.Services.WebService { [WebMethod()] public string[] GetMakeValue() { return new string[] { "Please select", "Ford", "Dodge" }; } [WebMethod()] public string[] GetChildValue(string parentID, string parentValue) { if (parentValue == "Please select") { return null; } string[] values; if (parentID == "ddlMake") { if (parentValue == "Ford") { values = new string[] { "Please select", "Explorer", "F150", "Mustang" }; } else if (parentValue == "Dodge") { values = new string[] { "Please select", "Durango", "Dakota", "Viper" }; } else { return new string[] { "Invalid Make value!" }; } } else if (parentID == "ddlModel") { switch (parentValue) { case "Explorer": case "Dakota": case "Viper": values = new string[] { "Please select", "Black", "Green", "Yellow" }; break; case "Durango": case "F150": case "Mustang": values = new string[] { "Please select", "White", "Red", "Blue" }; break; default: values = new string[] { "Invalid Model value!" }; break; } } else { return new string[] { "Invalid Category value!" }; } return values; } } }
クライアント側スクリプトから AJAX Web サービスの Web サービス メソッドを呼び出します。 手順 6 で追加したコードの下に、次のコードをコピーして貼り付けます。
<script type="text/javascript"> function pageLoad() { // call a Web service method with no parameters and the user context. KB_CascadingDDL_VB.WebService.GetMakeValue(SucceededCallbackWithContext, FailedCallback, "fillMake"); } // Event handler for ddlMake and ddlModel. // This function calls a Web service method // passing simple type parameters and the user context. function ddl_changed(sender) { // This initiates the call to the server-side method in your code-behind // The parameters are as follows: // 1st : Specify all the parameters expected by your code-behind method // (in this case there are 2: parentControl's ID, parentControl's selected text) // 2nd : Specify a callback method when the call succeeds // 3rd : Specify a callback method when the call fails(optional) // 4th : Specify a user context object (option - not shown) // (in this case we need to assign the parentControl's ID as the user context) KB_CascadingDDL_VB.WebService.GetChildValue(sender.id, sender[sender.selectedIndex].text, SucceededCallbackWithContext, FailedCallback, sender.id); } // This is the callback function called if the // Web service succeeded. It accepts the result // object, the user context, and the method name as // parameters. function SucceededCallbackWithContext(result, userContext) { if (userContext == "fillMake") { //fill the Make var ddl = $get('ddlMake'); } else if (userContext == "ddlMake") { // fill the Model var ddl = $get('ddlModel'); $get('ddlColor').options.length = 0; } else if (userContext == "ddlModel") { // fill the Color var ddl = $get('ddlColor'); } // clear the options ddl.options.length = 0; if (result) { var i = 0; for (var item in result) { // item is the key, result[item] is the value ddl.options.add(new Option(result[item], item)); i++; } } else { alert("Invalid! Please reset the selection!"); $get(userContext).focus(); } } // This is the callback function called if the // Web service failed. It accepts the error object // as a parameter. function FailedCallback(error) { if (error) { alert(error.get_message()); } else alert("An unexpeceted error occurred"); } //This the function to show the three DropDownLists'selection function DisplayResult() { $get("aResult").innerHTML = "You have selected a " + $get("ddlMake")[$get("ddlMake").selectedIndex].text + "," + $get("ddlModel")[$get("ddlModel").selectedIndex].text + "," + $get("ddlColor")[$get("ddlColor").selectedIndex].text + " car!"; } </script>
スクリプトから Web サービス メソッドを呼び出すことは非同期です。 戻り値を取得するか、要求がいつ返されたかを判断するには、成功したコールバック関数を指定する必要があります。 コールバック関数は、要求が正常に完了し、Web サービス メソッド呼び出しからの戻り値が含まれているときに呼び出されます。 エラーを処理するために失敗したコールバック関数を提供することもできます。 さらに、コールバック関数で使用するユーザー コンテキスト情報を渡すことができます。
AJAX Web サービスの Web サービス メソッドは、次の形式で呼び出すことができます。
theServiceNameSpace.WebServiceName.ServiceMethodName(parameters, SucceededCallbackFunctionName, FailedCallbackFunctionName, userContextString);
複数の Web サービス メソッド呼び出しから呼び出される 1 つの成功したコールバック関数を指定できます。 関数が異なる呼び出し元を区別できるようにするには、パラメーター内の関数にユーザー コンテキスト情報を渡します。
プロジェクトをビルドします。