zoukankan      html  css  js  c++  java
  • 简单三层+AJAX Control Toolkit实现dropdownlist无刷新联动

    这篇文章肯定有不足的地方,希望大家指正。谢谢
    另外平台是VS2005+SQL2000/2005

    参考信息:
    1,微软官方Using CascadingDropDown with a Database文档:http://www.asp.net/AJAX/AjaxControlToolkit/Samples/Walkthrough/CCDWithDB.aspx
    2,使用SQL Server对CascadingDropDown进行填充 http://blog.csdn.net/chen_cxb/archive/2008/03/05/2148565.aspx
    by conan304 2009年6月6日16:11:33

    一:前期准备工作
    1,AJAX的安装
    请参考微软的asp.net ajax页面:http://www.asp.net/AJAX/
    a,ASP.NET 2.0 AJAX Extensions 1.0 
          下载页面:http://www.asp.net/ajax/downloads/archive/
          具体下载地址:ASP.NET 2.0 AJAX Extensions 1.0 点击下载
    说明:页面上有ASP.NET 2.0 AJAX Extensions 1.0 Source Code可以下载。
    安装:下载后双击运行安装。

    b,AJAX Control Toolkit 的安装。
    注意:因为平台是VS2005,所以请下载1.0.
    下载页面:点击打开AJAX Control Toolkit Version 1.0.20229下载页面
    具体下载地址(包含源代码):点击下载AJAX Control Toolkit 1.Version 1.0.20229(包含源代码)
    安装:解压之后拷贝\AjaxControlToolkit\SampleWebSite\Bin\AjaxControlToolkit.dll 到所建ajax网站个bin目录下,添加AjaxControlToolkit.dll的引用。
    工具箱安装:建立ajax网站之后,右键工具箱--添加选项卡--AJAX Control Toolkit--选择项--浏览--找到 AjaxControlToolkit.dll 双击,确定就OK。

    c,数据库
    下载全国省市区数据库信息(SQL2005),然后附加。
    下载地址:https://files.cnblogs.com/conan304/area.zip

    二页面设计、代码。
    1,数据库的三个存储过程,分别得到省、市、区县信息。很简单。

    USE [area]
    GO
    /****** 对象:  StoredProcedure [dbo].[proc_getProvince]    脚本日期: 06/06/2009 16:58:48 ******/
    /****** 得到省份信息 ******/
    /****** by Conan304 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    create procedure [dbo].[proc_getProvince]
    as
    begin
        
    select province,provinceid from dbo.province
        
    order by [id]
    end
    GO
    /****** 对象:  StoredProcedure [dbo].[proc_getCity]    脚本日期: 06/06/2009 16:58:48 ******/
    /****** 得到城市信息 ******/
    /****** by Conan304 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    create procedure [dbo].[proc_getCity]
    (
        
    @provinceid varchar(20)
    )
    as
    begin
        
    select city,cityid from dbo.city    
        
    where father=@provinceid
        
    order by [id]
    end
    GO
    /****** 对象:  StoredProcedure [dbo].[proc_getArea]    脚本日期: 06/06/2009 16:58:47 ******/
    /****** 得到区县信息 ******/
    /****** by Conan304 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    create procedure [dbo].[proc_getArea]
    (
        
    @cityid varchar(20)
    )
    as
    begin
        
    select area,areaid from dbo.area    
        
    where father=@cityID
        
    order by [id]
    end
    GO

    2,建立DAL层。
    简单的代码:

    public class SQLHelper
        {        
            
    private readonly string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["SqlConnectionString"].ToString().Trim();        

            
    private SqlConnection conn;

            
    #region 打开数据库连接
            
    /// <summary>
            
    /// 打开数据库连接
            
    /// </summary>
            private void openDataBase()
            {
                
    if (conn == null)
                {
                    conn 
    = new SqlConnection();
                    conn.ConnectionString 
    = connectionString;
                }
                
    if (conn.State != ConnectionState.Open)
                {
                    conn.Open();
                }
            }
            
    #endregion

            
    #region 关闭数据库连接
            
    /// <summary>
            
    /// 关闭数据库连接
            
    /// </summary>
            private void closeDatabase()
            {
                
    if (conn == null)
                {
                    
    return;
                }
                
    else
                {
                    
    if (conn.State != ConnectionState.Closed)
                    {
                        conn.Close();
                    }
                }
            }
            
    #endregion

            
    #region 执行存储过程返回DataSet
            
    /// <summary>
            
    /// 执行存储过程返回DataSet
            
    /// </summary>
            
    /// <param name="procName">存储过程名</param>
            
    /// <param name="param">参数</param>
            
    /// <returns></returns>
            public DataSet getDataSetExecProc(string procName, SqlParameter[] param)
            {
                DataSet ds 
    = new DataSet();
                
    try
                {
                    
    this.openDataBase();
                    SqlCommand cmd 
    = new SqlCommand();
                    cmd 
    = conn.CreateCommand();
                    cmd.CommandText 
    = procName;
                    cmd.CommandType 
    = CommandType.StoredProcedure;
                    cmd.CommandTimeout 
    = 30;
                    SqlDataAdapter da 
    = new SqlDataAdapter();
                    da.SelectCommand 
    = cmd;
                    
    if (param != null)
                    {
                        
    foreach (SqlParameter sqlparam in param)
                        {
                            da.SelectCommand.Parameters.Add(sqlparam);
                        }
                    }
                    da.Fill(ds);
                    
                }
                
    catch
                {
                    ds
    =null;
                }
                
    finally
                {
                    
    this.closeDatabase();
                    
                }

                
    return ds;
            }

            
    /// <summary>
            
    /// 执行存储过程返回DataSet
            
    /// </summary>
            
    /// <param name="procName">存储过程名</param>
            
    /// <returns></returns>
            public DataSet getDataSetExecProc(string procName)
            {
                
    return getDataSetExecProc(procName, null);
            }
            
    #endregion
        }

    3,BLL层
    代码:

     public class BLL
        {
            
    public BLL()
            {

            }

            
    #region 得到省份信息
            
    /// <summary>
            
    /// 得到省份信息
            
    /// </summary>
            
    /// <returns></returns>
            public DataSet GetProvince()
            {
                DAL.SQLHelper sqlhelper 
    = new DAL.SQLHelper();
                DataSet ds 
    = new DataSet();
                ds 
    = sqlhelper.getDataSetExecProc("proc_getProvince");
                
    return ds;
            }
            
    #endregion

            
    #region 得到城市信息
            
    /// <summary>
            
    /// 得到城市信息
            
    /// </summary>
            
    /// <param name="provinceID"></param>
            
    /// <returns></returns>
            public DataSet GetCity(string provinceID)
            {
                DAL.SQLHelper sqlhelper 
    = new DAL.SQLHelper();
                DataSet ds 
    = new DataSet();
                SqlParameter[] param 
    =new SqlParameter("@provinceid", SqlDbType.VarChar, 20) };
                param[
    0].Value = provinceID;
                ds 
    = sqlhelper.getDataSetExecProc("proc_getCity", param);
                
    return ds;
            }
            
    #endregion

            
    #region 得到区县信息
            
    /// <summary>
            
    /// 得到区县信息
            
    /// </summary>
            
    /// <param name="cityID"></param>
            
    /// <returns></returns>
            public DataSet GetArea(string cityID)
            {
                DAL.SQLHelper sqlhelper 
    = new DAL.SQLHelper();
                DataSet ds 
    = new DataSet();
                SqlParameter[] param 
    =new SqlParameter("@cityid", SqlDbType.VarChar, 20) };
                param[
    0].Value = cityID;
                ds 
    = sqlhelper.getDataSetExecProc("proc_getArea", param);
                
    return ds;
            }
            
    #endregion
        }

    4,前台,拖入三个dropdownlist和三个CascadingDropDown.
    代码:

    <%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>

            
    <asp:DropDownList ID="DropDownList1" runat="server">
            
    </asp:DropDownList>
            
    <asp:DropDownList ID="DropDownList2" runat="server">
            
    </asp:DropDownList>
            
    <asp:DropDownList ID="DropDownList3" runat="server">
            
    </asp:DropDownList>
            
            
    <cc1:CascadingDropDown ID="CascadingDropDown1" runat="server" Category="Province" LoadingText="正在加载省" ParentControlID="" PromptText="选择省" 
                ServiceMethod
    ="GetProvince" ServicePath="CityService.asmx" TargetControlID="DropDownList1" >
            
    </cc1:CascadingDropDown>            
            
    <cc1:CascadingDropDown ID="CascadingDropDown2" runat="server" Category="City" LoadingText="正在加载市." ParentControlID="DropDownList1" PromptText="选择市"
                ServiceMethod
    ="GetCity" ServicePath="CityService.asmx" TargetControlID="DropDownList2" >
            
    </cc1:CascadingDropDown>
            
    <cc1:CascadingDropDown ID="CascadingDropDown3" runat="server" Category="Area" LoadingText="正在加载区县." ParentControlID="DropDownList2" PromptText="选择区县"
                ServiceMethod
    ="GetArea" ServicePath="CityService.asmx" TargetControlID="DropDownList3" >
            
    </cc1:CascadingDropDown>

     说明(转自:http://blog.csdn.net/chen_cxb/archive/2008/03/05/2148565.aspx):

    1)CascadingDropDown控件的重要属性:

    TargetControlID : 指定要扩展的DropDownList的ID
    Category : DropDownList表示的类别名称,在WebMethod中会用到
    PromptText : 没有选择时显示的文字
    LoadingText : 加载数据时显示的文字
    ServicePath : 获取数据的Web Service,为每个DropDownList都要指定
    ServiceMethod : 获取数据的Web Method
    ParentControlID : 要扩展的DropDownList的父控件ID
    SelectedValue : 默认的选择项的值

    刚才,我们添加的[webMethod]是GetProvince,它作为CascadingDropDown控件cascadingDropDown1的获取数据的方法 (cascadingDropDownCountry中的ServiceMethod="GetProvince"来定义这个属性),而将它关联的是DropDownList 中 DropDownList1控件(cascadingDropDown1中的TargetControlID="DropDownList1"来定义)。而另外两个City和Area控件所关联的cascadingDropDown2和 cascadingDropDown3控件呢?他们的[ServiceMethod]方法又是什么呢?我们可以看到在这两个CascadingDropDown控件的后面有一个ServiceMethod=""的属性,这个就是配置了他们的获取数据的方法。又上面的配置信息,我们可以得到他们的方法分别是GetCity和GetArea方法,这个需要我们在.cs中重新定义,类似于我们操作第一个一样。

    不同的是,由于我们的第一个没有其关联的父选项DropDownList,所以,在获取数据的时候,直接就可以利用sql句获取我们想得到的数据,但是,第二个和第三个却都拥有父选项,换句话说,他们的内容是受到他们的父选项控制的,比如,我们只有在第一个DropDownList中选择了省份,我们的才能在第二个DropDownList中,动态的加载这个省份的所有城市,我们也只有选择了第二个DropDownList中的城市,我们才能在第三个DropDownList中动态添加该城市的所有区县。他们是具有父子之间的依赖关系的。

    那么,他们之间是怎么联系的呢?答案就在代码中。

    请注意,前台CascadingDropDown控件代码中的这个配置

               ParentControlID="Province"

          Category="city"

    这两个配置的意思就是,ParentControlID定义了CascadingDropDown控件所绑定的DropDownList的控件的父选项是是什么。

    而Category表示的是,它所处的类别,是用户自定义的,方便在多个CascadingDropDown控件调用一个[webMethod]的时候,实现重载。

    当我们的子下拉控件绑定到父下拉的时候,根据这个控件的特色,就会产生如下的联系:

    1.当父下拉控件不被选择的时候,子下拉控件是呈灰色不可操作的

    2.当父下拉空间被选择的时候,子下拉空间就在其被选择后,根据父控件被选择的内容,自动加载预定信息

         他们之间的联系,就是通过ParentControlID设定后,在子控件获取数据的方法体中knownCategoryValues获得。

            [System.Web.Services.WebMethodAttribute(), System.Web.Script.Services.ScriptMethodAttribute()]

        public static CascadingDropDownNameValue[] GetCountries(string knownCategoryValues, string category)

    knownCategoryValues的传递是以字符串的形式传递的,它的主要形式如下:

    "provincename:000;”

    "provincename:000;”Provinces:000010;"

    传递一次,它就将会随之自动的增加一次。Provincename是我们下拉框选项的显示内容(text),000是下拉框在这个显示内容下的值(value).

    他们是从哪里来的呢,是从我们的父下拉控件中传递过来的,如

               values.Add(new CascadingDropDownNameValue("北京", "000"));

    这里面name就是“北京”,value就是“000”。

    既然如此,我们就可以按照如下方式进行操作,获取父控件传递的信息,如下

    方法一:截取字符串到字符串数组

     string[] categoryValues = knownCategoryValues.Split(':', ';');

    方法二:利用数据字典

     StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);

    这两种方法是殊途同归。


    新建webservice,页面名称CityService.asmx,有三个[WebMethod],分别是:GetProvince,GetCity,GetArea
    完整代码:

    using System;
    using System.Data;
    using System.Web;
    using System.Collections;
    using System.Web.Services;
    using System.Web.Services.Protocols;
    using System.ComponentModel;
    using System.Collections.Generic;//添加泛型
    using AjaxControlToolkit;//
    using System.Collections.Specialized;//StringDictionary

    namespace myAJAX090606
    {
        
    /// <summary>
        
    /// CityService 的摘要说明
        
    /// </summary>
        [WebService(Namespace = "http://tempuri.org/")]
        [WebServiceBinding(ConformsTo 
    = WsiProfiles.BasicProfile1_1)]
        [System.Web.Script.Services.ScriptService] 
    //注意添加此属性,否则会报错

        
    public class CityService : System.Web.Services.WebService
        {
            
    #region 得到省份信息
            
    /// <summary>
            
    /// 得到省份信息 请参考微软的文档:http://www.asp.net/AJAX/AjaxControlToolkit/Samples/Walkthrough/CCDWithDB.aspx
            
    /// </summary>
            
    /// <returns></returns>
            [WebMethod]
            
    public CascadingDropDownNameValue[] GetProvince()
            {
                DataSet ds 
    =new DataSet();
                BLL.BLL newBLL 
    = new BLL.BLL();
                ds 
    = newBLL.GetProvince();
                List
    <CascadingDropDownNameValue> values=new List<CascadingDropDownNameValue>();
                
    if (ds.Tables.Count > 0)
                {
                    
    foreach (DataRow dr in ds.Tables[0].Rows)
                    {
                        values.Add(
    new CascadingDropDownNameValue(dr["province"].ToString().Trim(),dr["provinceid"].ToString().Trim()));
                    }
                }
                
    return values.ToArray();
            }
            
    #endregion

            
    #region 得到城市信息
            
    /// <summary>
            
    /// 得到城市信息
            
    /// </summary>
            
    /// <param name="knownCategoryValues">得到当前选择的字符串信息包含name/value</param>
            
    /// <param name="category"></param>
            
    /// <returns></returns>
            [WebMethod]
            
    public CascadingDropDownNameValue[] GetCity(string knownCategoryValues, string category)
            {

                StringDictionary kv 
    =CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);

                
    string provinceID;
                
    if (!kv.ContainsKey("Province"))
                {
                    
    return null;
                }
                
    else
                {
                    provinceID 
    = kv["Province"].ToString();
                }

                DataSet ds 
    = new DataSet();
                BLL.BLL newBLL 
    = new BLL.BLL();
                ds 
    = newBLL.GetCity(provinceID);
                List
    <CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>();
                
    if (ds.Tables.Count > 0)
                {
                    
    foreach (DataRow dr in ds.Tables[0].Rows)
                    {
                        values.Add(
    new CascadingDropDownNameValue(dr["city"].ToString().Trim(), dr["cityid"].ToString().Trim()));
                    }
                }
                
    return values.ToArray();
            }
            
    #endregion

            
    #region 得到区县信息
            
    /// <summary>
            
    /// 得到区县信息
            
    /// </summary>
            
    /// <param name="knownCategoryValues"></param>
            
    /// <param name="category"></param>
            
    /// <returns></returns>
            [WebMethod]
            
    public CascadingDropDownNameValue[] GetArea(string knownCategoryValues, string category)
            {
                StringDictionary kv 
    = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);

                
    string provinceID;
                
    if (!kv.ContainsKey("City"))
                {
                    
    return null;
                }
                
    else
                {
                    provinceID 
    = kv["city"].ToString();
                }

                DataSet ds 
    = new DataSet();
                BLL.BLL newBLL 
    = new BLL.BLL();
                ds 
    = newBLL.GetArea(provinceID);
                List
    <CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>();
                
    if (ds.Tables.Count > 0)
                {
                    
    foreach (DataRow dr in ds.Tables[0].Rows)
                    {
                        values.Add(
    new CascadingDropDownNameValue(dr["area"].ToString().Trim(), dr["areaid"].ToString().Trim()));
                    }
                }
                
    return values.ToArray();
            }
            
    #endregion
        }
    }

     注意:webservice一定要加上System.Web.Script.Services.ScriptService 属性。不然会报错。


    三,实现效果:

    最后附上ParseKnownCategoryValuesString方法的源代码:

            public static StringDictionary ParseKnownCategoryValuesString(string knownCategoryValues)
            {
                
    // Validate parameters
                if (null == knownCategoryValues)
                {
                    
    throw new ArgumentNullException("knownCategoryValues");
                }

                StringDictionary dictionary 
    = new StringDictionary();
                
    if (null != knownCategoryValues)
                {
                    
    // Split into category/value pairs
                    foreach (string knownCategoryValue in knownCategoryValues.Split(';'))
                    {
                        
    // Split into category and value
                        string[] knownCategoryValuePair = knownCategoryValue.Split(':');
                        
    if (2 == knownCategoryValuePair.Length)
                        {
                            
    // Add the pair to the dictionary
                            dictionary.Add(knownCategoryValuePair[0].ToLowerInvariant(), knownCategoryValuePair[1]);
                        }
                    }
                }
                
    return dictionary;
            }
  • 相关阅读:
    记录java设计模式中适配器模式和装饰器模式和代理模式的区别
    excel工具类记录
    docker搭建图床 chevereto 非常方便
    docker 安装mysql
    rabbitmq学习之路(八)
    理解js中的作用域,作用域链以及闭包
    浏览器解析js的顺序
    javacript 组合使用构造函数模式和原型模式
    js垃圾回收机制与深拷贝和浅拷贝
    ES6 变量的解构赋值
  • 原文地址:https://www.cnblogs.com/conan304/p/1497672.html
Copyright © 2011-2022 走看看