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