简单三层+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),然后附加。
下载地址:http://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 属性。不然会报错。


三,实现效果:
简单三层+AJAX Control Toolkit实现dropdownlist无刷新联动

 

最后附上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;
        }

 

你可能感兴趣的:(Ajax)