一路向前走

其中的代码,如果您有更好的改进,请一定提出您的宝贵意见及建议

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::
  91 随笔 :: 3 文章 :: 94 评论 :: 0 引用

1.功能描述

对标准DropDownList控件的扩展,是产生级联菜单效果的ASP.NET AJAX控件.

1.控件属性说明

  • TargetControlID - 扩展的DropDownList控件ID.
  • Category - 类别.为绑定的DropDownList的所有下拉值指定的一个类别.比如,省下拉框的下拉值,我们可以指定一个类别为:Province
  • PromptText - 可选属性. 在选择下拉框选项前,下拉框中显示的文字.比如:请选择.
  • PromptValue - PromptText 选项所对应的选项值.
  • EmptyText - 在下拉框数据源为空时显示的文字.
  • EmptyValue - EmptyText 选项对应的选项值.
  • LoadingText - 在加载下拉框选项过程中显示的文字. 比如:数据加载中....
  • ServicePath - 用于返回下拉框数据源的WebService地址. ServiceMethod 指定的方法是页面内方法,此属性为空
  • ServiceMethod - 用于返回下拉框数据源的对应方法名.不包含签名.仅是方法名.

     但此方法必须严格遵守下面的签名:

 

public CascadingDropDownNameValue[] GetCityForProvince(string knownCategoryValues, string category)
{
   ...
}

 

 

也就是说,其只的参数名knownCategoryValues,category都不可以使用其它的名字,参数类型也不可以使用其它的类型.

 

 2.使用

2.1 前端代码

 

代码
<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" EnableEventValidation="false" 
    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;
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

posted on 2010-05-11 17:37 Adair 阅读(...) 评论(...) 编辑 收藏