注:本文应之邀,翻译自:http://atlas.asp.net/atlastoolkit/Walkthrough/CCDWithDB.aspx,不保证内容或示例程序的正确性。
关于Atlas Control Toolkit,请参考:
- "Atlas" Control Toolkit更新发布(Version 1.0.60504.0)
- Atlas Control ToolKit 发布
CascadingDropDown(中文可译作“联动下拉菜单组”,演示程序请见:http://atlas.asp.net/atlastoolkit/CascadingDropDown/CascadingDropDown.aspx)是这个Control Toolkit中的一个Control。在Toolkit中附带的Demo中,CascadingDropDown使用了一个XML作为数据源。这样,一个常见的问题就是如何使用数据库来代替XML。本文因此而生,将介绍如何从数据库中取得数据并填充到CascadingDropDown中。
首先建立一个Atlas网站(或应用程序),并在项目中添加对AtlasControlToolkit.dll的引用。
新建一个Atlas页面,添加如下三个DropDownList到页面中:
<
div
>
Make:
<
asp:DropDownList
ID
="ddlMake"
runat
="server"
/><
br
/>
Model:
<
asp:DropDownList
ID
="ddlModel"
runat
="server"
/><
br
/>
Color:
<
asp:DropDownList
ID
="ddlColor"
runat
="server"
/>
<
br
/>
<
asp:Button
ID
="Button1"
runat
="server"
Text
="Submit"
/>
</
div
>
在ASPX页面的开头部分注册Atlas Control Toolkit:
<
%@ Register
Assembly
="AtlasControlToolkit"
Namespace
="AtlasControlToolkit"
TagPrefix
="atlasToolkit"
%
>
在页面上添加这个CascadingDropDown extender。
<
atlasToolkit:CascadingDropDown
ID
="CascadingDropDown1"
runat
="server"
/>
在运行时,这个extender会异步的调用指定的Web Service,在这个Web Service中,我们需要添加如下一个Web Method。(注意:您不能改变下述Web Method签名中的参数名。)
[WebMethod]
public
CascadingDropDownNameValue[] GetColorsForModel(
string
knownCategoryValues,
string
category
)
CascadingDropDown extender将把当前被选中的DropDownList中的key和value通过knownCategoryValues参数传给这个Web Method。例如,若当前该extender需要取得Color中应该填充的值,则knownCategoryValues参数将包含目前选中的Make和Model的值。
CascadingDropDown类有一个Helper方法,可以帮助您取得knownCategoryValues参数中的值:
StringDictionary kv
=
CascadingDropDown
.ParseKnownCategoryValuesString(knownCategoryValues);
上述方法返回一个StringDictionary对象,包含了当前被选中的若干个DropDownList中的name/value对。设想当前Make和Model的值已经被选好,您需要根据他们访问数据库返回Color的可选值。则示例代码应该如下所示:
[WebMethod]
public
CascadingDropDownNameValue[] GetColorsForModel(
string
knownCategoryValues,
string
category)

{
StringDictionary kv =
CascadingDropDown.ParseKnownCategoryValuesString(
knownCategoryValues);
int modelId;
if (!kv.ContainsKey("Model") ||
!Int32.TryParse(kv["Model"], out modelId))

{
return null;
}

CarsTableAdapters.ColorTableAdapter adapter =
new CarsTableAdapters.ColorTableAdapter();
Cars.ColorDataTable colorTable =
adapter.GetColorsForModel(modelId);

List<CascadingDropDownNameValue> values =
new List<CascadingDropDownNameValue>();
foreach (DataRow dr in colorTable)

{
values.Add(new CascadingDropDownNameValue(
(string) dr["Color"],
dr["ColorID"].ToString()));
}
return values.ToArray();
}
让我们再回来看看CascadingDropDown extender的声明:
<
atlasToolkit:CascadingDropDown
ID
="CascadingDropDown1"
runat
="server"
>
<
atlasToolkit:CascadingDropDownProperties
TargetControlID
="ddlMake"
Category
="Make"
PromptText
="Select a manufacturer"
ServicePath
="CarsService.asmx"
ServiceMethod
="GetCarMakes"
/>
</
atlasToolkit:CascadingDropDown
>
其中TargetControlID用来指定extender将要扩展的DropDownList。PromptText指定该DropDownList中没有被选项时的提示文字。ServicePath 与ServiceMethod指定了获取该DropDownList中数据的Web Service与其中的Web Method。
我们也可以在VS的设计器中更改上述属性:

注意到ParentControlID属性指定了当前DropDownList的“父”DropDownList。当“父”DropDownList被选择后,CascadingDropDown extender将自动调用服务器的相应方法获取并设定当前DropDownList的值,这样也就产生了“联动”的效果。
在我们的示例程序中,CascadingDropDown extender的声明应该如下所示:
<
atlasToolkit:CascadingDropDown
ID
="CascadingDropDown1"
runat
="server"
>
<
atlasToolkit:CascadingDropDownProperties
TargetControlID
="ddlMake"
Category
="Make"
PromptText
="Select a manufacturer"
ServicePath
="CarsService.asmx"
ServiceMethod
="GetCarMakes"
/>
<
atlasToolkit:CascadingDropDownProperties
TargetControlID
="ddlModel"
ParentControlID
="ddlMake"
PromptText
="Please select a model"
ServiceMethod
="GetModelsForMake"
ServicePath
="CarsService.asmx"
Category
="Model"
/>
<
atlasToolkit:CascadingDropDownProperties
TargetControlID
="ddlColor"
ParentControlID
="ddlModel"
PromptText
="Please select a color"
ServiceMethod
="GetColorsForModel"
ServicePath
="CarsService.asmx"
Category
="Color"
/>
</
atlasToolkit:CascadingDropDown
>
完成后的Web Service如下所示:
Full Web Service Code
using System;
using System.Web;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web.Services;
using System.Web.Services.Protocols;
using AtlasControlToolkit;
using System.Data;
using System.Data.SqlClient;


/**//// <summary>
/// Summary description for CarData
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class CarData : System.Web.Services.WebService


{
public CarData()

{
//Uncomment the following line if using designed components
//InitializeComponent();
}

[WebMethod]
public CascadingDropDownNameValue[] GetMakes(
string knownCategoryValues,
string category)

{
CarsTableAdapters.MakeTableAdapter makeAdapter =
new CarsTableAdapters.MakeTableAdapter();
Cars.MakeDataTable makes = makeAdapter.GetMakes();
List<CascadingDropDownNameValue> values =
new List<CascadingDropDownNameValue>();
foreach (DataRow dr in makes)

{
string make = (string)dr["Make"];
int makeId = (int)dr["MakeID"];
values.Add(new CascadingDropDownNameValue(
make, makeId.ToString()));
}
return values.ToArray();
}

[WebMethod]
public CascadingDropDownNameValue[] GetModelsForMake(
string knownCategoryValues,
string category)

{
StringDictionary kv =
CascadingDropDown.ParseKnownCategoryValuesString(
knownCategoryValues);
int makeId;
if (!kv.ContainsKey("Make") ||
!Int32.TryParse(kv["Make"], out makeId))

{
return null;
}
CarsTableAdapters.ModelTableAdapter makeAdapter =
new CarsTableAdapters.ModelTableAdapter();
Cars.ModelDataTable models =
makeAdapter.GetModelsForMake(makeId);
List<CascadingDropDownNameValue> values =
new List<CascadingDropDownNameValue>();
foreach (DataRow dr in models)

{
values.Add(new CascadingDropDownNameValue(
(string)dr["Model"], dr["ModelID"].ToString()));
}
return values.ToArray();
}

[WebMethod]
public CascadingDropDownNameValue[] GetColorsForModel(
string knownCategoryValues,
string category)

{
StringDictionary kv =
CascadingDropDown.ParseKnownCategoryValuesString(
knownCategoryValues);
int modelId;
if (!kv.ContainsKey("Model") ||
!Int32.TryParse(kv["Model"], out modelId))

{
return null;
}
CarsTableAdapters.ColorTableAdapter adapter =
new CarsTableAdapters.ColorTableAdapter();
Cars.ColorDataTable colorTable =
adapter.GetColorsForModel(modelId);
List<CascadingDropDownNameValue> values =
new List<CascadingDropDownNameValue>();
foreach (DataRow dr in colorTable)

{
values.Add(new CascadingDropDownNameValue(
(string)dr["Color"], dr["ColorID"].ToString()));
}
return values.ToArray();
}
}
最后要注意的是在运行时,页面的EventValidation应该被禁用。因为EventValidation用来确保页面上控件的实际值与页面从服务器发送过来时的值相同,而这里显然是不可能的。
转载于:https://www.cnblogs.com/dflying/archive/2006/05/08/Atlas_Control_Toolkit_Demo__Using_CascadingDropDown_with_a_Database.html