1.功能描述
对标准DropDownList控件的扩展,是产生级联菜单效果的ASP.NET AJAX控件.
1.控件属性说明
- TargetControlID - 扩展的DropDownList控件ID.
- Category - 类别.为绑定的DropDownList的所有下拉值指定的一个类别.比如,省下拉框的下拉值,我们可以指定一个类别为:Province
- PromptText - 可选属性. 在选择下拉框选项前,下拉框中显示的文字.比如:请选择.
- PromptValue - PromptText 选项所对应的选项值.
- EmptyText - 在下拉框数据源为空时显示的文字.
- EmptyValue - EmptyText 选项对应的选项值.
- LoadingText - 在加载下拉框选项过程中显示的文字. 比如:数据加载中....
- ServicePath - 用于返回下拉框数据源的WebService地址. ServiceMethod 指定的方法是页面内方法,此属性为空
- ServiceMethod - 用于返回下拉框数据源的对应方法名.不包含签名.仅是方法名.
但此方法必须严格遵守下面的签名:
{
...
}
也就是说,其只的参数名knownCategoryValues,category都不可以使用其它的名字,参数类型也不可以使用其它的类型.
2.使用
2.1 前端代码
CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<div style="height: 446px">
<asp:DropDownList ID="DropDownList1" runat="server" Height="16px" Width="131px">
</asp:DropDownList>
<ajaxToolkit:CascadingDropDown ID="CascadingDropDown1" Category="Province"
PromptText="please select province" ServicePath="CityService.asmx"
ServiceMethod="GetProvince" TargetControlID="DropDownList1"
runat="server">
</ajaxToolkit:CascadingDropDown>
<asp:DropDownList ID="DropDownList2" runat="server" Height="16px" Width="104px" >
</asp:DropDownList>
<ajaxToolkit:CascadingDropDown ID="CascadingDropDown2" Category="City"
PromptText="please select city" ServicePath="CityService.asmx"
ServiceMethod="GetCityForProvince" TargetControlID="DropDownList2"
ParentControlID="DropDownList1" runat="server">
</ajaxToolkit:CascadingDropDown>
<asp:DropDownList ID="DropDownList3" runat="server" Height="16px" Width="131px"
onselectedindexchanged="DropDownList3_SelectedIndexChanged">
</asp:DropDownList>
<ajaxToolkit:CascadingDropDown ID="CascadingDropDown3" Category="Town"
PromptText="please select town" ServicePath="CityService.asmx"
ServiceMethod="GetTownsForCity" TargetControlID="DropDownList3"
ParentControlID="DropDownList2" runat="server">
</ajaxToolkit:CascadingDropDown>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</div>
</asp:Content>
2.2 WebService:CityService.asmx代码
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Data;
using AjaxControlToolkit;
using System.Collections.Specialized;
/// <summary>
/// Summary description for CityService
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// 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 CityService : System.Web.Services.WebService {
public CityService () {
//Uncomment the following line if using designed components
//InitializeComponent();
}
/// <summary>
/// 构建省对应的下拉框的数据源.
/// <remarks>
/// 这里是手动创建了一个表格. 按实际情况,可以从数据库中取值
/// </remarks>
/// </summary>
/// <returns></returns>
public DataTable GetProvinceTable()
{
DataTable dt = new DataTable();
DataColumn dc;
DataRow dr;
dc = new DataColumn();
dc.ColumnName = "province_name";
dc.DataType = System.Type.GetType("System.String");
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "province_value";
dc.DataType = System.Type.GetType("System.String");
dt.Columns.Add(dc);
dr = dt.NewRow();
dr["province_name"] = "广东";
dr["province_value"] = "guangdong";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["province_name"] = "江西";
dr["province_value"] = "jiangxi";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["province_name"] = "山西";
dr["province_value"] = "shanxi";
dt.Rows.Add(dr);
return dt;
}
/// <summary>
/// 构建市对应的下拉框的数据源.
/// <remarks>
/// 这里是手动创建了一个表格. 按实际情况,可以从数据库中取值
/// </remarks>
/// </summary>
/// <returns></returns>
public DataRow[] GetCityTable(string provinceid)
{
DataTable dt = new DataTable();
DataColumn dc;
DataRow dr;
dc = new DataColumn();
dc.ColumnName = "province_value";
dc.DataType = System.Type.GetType("System.String");
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "city_name";
dc.DataType = System.Type.GetType("System.String");
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "city_value";
dc.DataType = System.Type.GetType("System.String");
dt.Columns.Add(dc);
dr = dt.NewRow();
dr["province_value"] = "guangdong";
dr["city_name"] = "广州";
dr["city_value"] = "guangzhou";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["province_value"] = "guangdong";
dr["city_name"] = "深圳";
dr["city_value"] = "shengzhen";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["province_value"] = "jiangxi";
dr["city_name"] = "南昌";
dr["city_value"] = "nanchang";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["province_value"] = "jiangxi";
dr["city_name"] = "上饶";
dr["city_value"] = "shangrao";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["province_value"] = "shanxi";
dr["city_name"] = "太原";
dr["city_value"] = "taiyuan";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["province_value"] = "shanxi";
dr["city_name"] = "刑台";
dr["city_value"] = "xingtai";
dt.Rows.Add(dr);
DataRow[] drs = dt.Select("province_value='" + provinceid + "'");
return drs;
}
/// <summary>
/// 构建区对应的下拉框的数据源.
/// <remarks>
/// 这里是手动创建了一个表格. 按实际情况,可以从数据库中取值
/// </remarks>
/// </summary>
/// <returns></returns>
public DataRow[] GetTownTable(string cityid)
{
DataTable dt = new DataTable();
DataColumn dc;
DataRow dr;
dc = new DataColumn();
dc.ColumnName = "city_value";
dc.DataType = System.Type.GetType("System.String");
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "town_name";
dc.DataType = System.Type.GetType("System.String");
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "town_value";
dc.DataType = System.Type.GetType("System.String");
dt.Columns.Add(dc);
dr = dt.NewRow();
dr["city_value"] = "guangzhou";
dr["town_name"] = "花都";
dr["town_value"] = "huadu";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["city_value"] = "shengzhen";
dr["town_name"] = "南山";
dr["town_value"] = "nanshan";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["city_value"] = "nanchang";
dr["town_name"] = "山青山";
dr["town_value"] = "shanqingshan";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["city_value"] = "shangrao";
dr["town_name"] = "余干";
dr["town_value"] = "yugan";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["city_value"] = "taiyuan";
dr["town_name"] = "杏花区";
dr["town_value"] = "xinhuaqu";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["city_value"] = "xingtai";
dr["town_name"] = "会宁镇";
dr["town_value"] = "huining";
dt.Rows.Add(dr);
DataRow[] drs = dt.Select("city_value='" + cityid + "'");
return drs;
}
[WebMethod]
public CascadingDropDownNameValue[] GetProvince(string knownCategoryValues, string category)
{
List<CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>();
DataTable provinces = GetProvinceTable();// 获取省对应的下拉框的数据源
// 将DataTable数据转换为指定的List<CascadingDropDownNameValue>列表
foreach (DataRow dr in provinces.Rows)
{
string province = dr["province_name"].ToString();
string provinceid = dr["province_value"].ToString();
values.Add(new CascadingDropDownNameValue(province, provinceid));
}
return values.ToArray();
}
[WebMethod]
public CascadingDropDownNameValue[] GetCityForProvince(string knownCategoryValues, string category)
{
// 这里的参数knownCategoryValues就是上级下拉框的Category和其值.格式是:Province:guangdong
// 这里的参数category 就是调用了这个方法的CascadingDropDown的Category值.如:City
StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);
string provinceid;
// 判断是不是省对应的下拉框传过来的值
if (!kv.ContainsKey("Province"))
{
return null;
}
provinceid = kv["Province"].ToString();// 获取省份的值
DataRow[] citys = GetCityTable(provinceid);// 通过省过滤城市
List<CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>();
// 转换为指定的List<CascadingDropDownNameValue>列表
foreach (DataRow dr in citys)
{
values.Add(new CascadingDropDownNameValue((string)dr["city_name"], dr["city_value"].ToString()));
}
return values.ToArray();
}
[WebMethod]
public CascadingDropDownNameValue[] GetTownsForCity(string knownCategoryValues, string category)
{
StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);
string cityid;
if (!kv.ContainsKey("City"))
{
return null;
}
cityid = kv["City"].ToString();
DataRow[] towns = GetTownTable(cityid);
List<CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>();
foreach (DataRow dr in towns)
{
values.Add(new CascadingDropDownNameValue((string)dr["town_name"], dr["town_value"].ToString()));
}
return values.ToArray();
}
}
3.试验过程中碰到的问题及原因
3.1 运行后,三个下拉框都没有下拉框.且显示空白
原因:将方法中的参数knownCategoryValues,写成knownCategoryValue了.
3.2 选择下拉框值,页面都会刷新.
原因:将加在每个DropDownList中的AutoPostBack="true" 去掉.
4.总结
4.1 方法签名是严格的,不能自定义
4.2 使用AJAX类库,都要引用在页面的顶端加个
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
4.3 在级联下拉中,每个下拉框都需要一个CascadingDropDown.
4.4 CascadingDropDown中的Category属性是为对应的DropDownList选项值指一个自定义的类别.名称可以随便.但各个CascadingDropDown的Category必须得不同.
4.5 在获取下拉框数据源的方法中,一般都需要定义一个
StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);
手动往kv中添加选项,再使用ToArray()方法返回.
4.6 还有一点,WebService需要将[System.Web.Script.Services.ScriptService]打开.这样,脚本才能访问到.
5.参考文档
http://www.asp.net/ajaxlibrary/act_CascadingDropdown.ashx
http://hi.baidu.com/legend_fly/blog/item/59c7b91d27e440ffe1fe0b67.html