使用SQL Server对CascadingDropDown进行填充

    需求是这样的,有三个DropDownList控件,分别用来选择国家,省份,和城市。他们具有依赖关系,当我选择某个国家的时候,我需要无刷新的动态加载这个国家的所有的省份,同样,当我选择某个省份的时候,我需要无刷新的选择这个省份的所有的城市。而这些国家,省份和城市的数据全部是储存在sql server数据库中。

 

我看了这个需求后,我打算利用AjaxToolKit中的CascadingDropDown控件加上asp.net2.0自带的DropDownList来实现。

具体过程如下:

   

    CascadingDropDown数据控件默认的填充数据源是基于XML的,它是通过webservice去调用XML文件,通过节点来区分子节,然后加载相关的数据。

网上关于如何来加载XML数据源的例子很多,但是这里的需求决定了,我们得需要利用基于数据库的数据填充方式。

首先,我们需要在我们的web-site中建立一个webservice,它用来提供CascadingDropDown的数据源。(在最新七月的推出的版本中,这里可以不用添加webService,而是直接利用在.cs文件中添加内嵌方法的方式来设定,但不管怎么样,他们在具体实现method中是殊途同归的,这里不做过多讲述)

一般来说,有多少个CascadingDropDown,就有多少个[webMethod],但是,你也可以根据系统的条件以及自己的设计爱好,利用category属性合理的去重载这些方法。

我们在.cs代码页面添加如下代码,以方便前台页面的调用和配置。

 

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

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

    {

        //

        // 如果采用了webService架构,这里就直接去调用webService中的[webMethod]076月份后的版本默认都不采用webService

        // 而是直接将webService中的[webMethod]实现移动到这个方法体内

        //

    }

 

然后建立数据连结池,可以利用SqlDataAdapter或者SqlDataReader来访问数据库(由于数据量小,建议使用SqlDataReader)

 

        string selectCommand = "SELECT * FROM [dbo].[tbCountryRegion] WHERE [RegionType] = 3";

        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString))

        {

            SqlCommand sqlcmd = new SqlCommand(selectCommand, conn);

                 conn.Open();

            SqlDataReader reader = sqlcmd.ExecuteReader();

     … …

 

把检索出来的数据转换成CascadingDropDownNameValue类型(该类型在using AjaxControlToolkit命名空间中)

 

            List<CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>();

            while (reader.Read())

            {

                values.Add(new CascadingDropDownNameValue(reader[1].ToString(), reader[0].ToString()));

            }

            reader.Close();

 

     当数据为空的时候,建议设定一个默认值

 

            if (values.Count == 0)

            {

                values.Add(new CascadingDropDownNameValue("中国", "000"));

       }

 

最终利用返型来存储这些数据,

 

        return values.ToArray();

    }

 

最后,我们需要在aspx页面上配置我们的控件信息和属性

首先是我们的页面显示空间DropDownList

 

        <asp:DropDownList ID=" CountryRegion " runat="server">

        </asp:DropDownList>

        <asp:DropDownList ID=" Province " runat="server">

        </asp:DropDownList>

        <asp:DropDownList ID=" CityName " runat="server">

        </asp:DropDownList>

 

     然后添加一个我们运行CascadingDropDown控件需要的脚本管理

        <asp:ScriptManager ID="ScriptManager1" runat="server">

        </asp:ScriptManager>

 

最后添加主角CascadingDropDown控件,并配置相关属性和信息

 

         <ajaxToolkit:CascadingDropDown ID="cascadingDropDownCountry" runat="server" ServiceMethod="GetCountries"

            TargetControlID="CountryRegion" UseContextKey="True" Category ="provincename" PromptText="请选择国家" LoadingText="正在加载国家信息...">

        </ajaxToolkit:CascadingDropDown>

        <ajaxToolkit:CascadingDropDown ID="cascadingDropDownProvince" runat="server" ParentControlID="CountryRegion"

            TargetControlID="Province" Category="Provinces" ServiceMethod ="GetProvincesForCountry" UseContextKey="True" PromptText="请选择省份" LoadingText="正在加载省份(地区)信息...">

        </ajaxToolkit:CascadingDropDown>

        <ajaxToolkit:CascadingDropDown ID="cascadingDropDownCity" runat="server" Category="city" ParentControlID="Province"

            ServiceMethod="GetCitiesForProvince" TargetControlID="CityName" UseContextKey="True" PromptText="请选择城市" LoadingText="正在加载城市信息">

    </ajaxToolkit:CascadingDropDown>

 

刚才,我们添加的[webMethod]GetCountries它作为CascadingDropDown控件cascadingDropDownCountry的获取数据的方法 (cascadingDropDownCountry 中的ServiceMethod="GetCountries"来定义这个属性),而将它关联的是DropDownList CountryRegion控件(cascadingDropDownCountry 中的TargetControlID="CountryRegion"来定义)。而另外两个ProvinceCityName控件所关联的cascadingDropDownProvince cascadingDropDownCity控件呢?他们的[ServiceMethod]方法又是什么呢?我们可以看到在这两个CascadingDropDown控件的后面有一个ServiceMethod=""的属性,这个就是配置了他们的获取数据的方法。又上面的配置信息,我们可以得到他们的方法分别是CountryRegionGetCitiesForProvince方法,这个需要我们在.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);

 

这两种方法是殊途同归。

我采取的是第一种方法,简单易懂。

在获取上面传来的值信息之后,我们就可以进行数据检索操作,并去获取我们想要的数据了

 

string selectCommand = "SELECT * FROM [dbo].[tbCountryRegion] WHERE [RegionType] = 2 AND [RegionID] LIKE '" + categoryValues[1]+ "%'";

 

下面的过程和第一个控件的这个方法一样,利用SqlDataReader来访问数据库,把检索出来的数据转换成CascadingDropDownNameValue类型,然后进行输出。

不管有多少级下拉框,我们都可以利用这个方法来如法炮制的操作。

 

完成后,我们就可以设定端点F5一下,欣赏自己的劳动成果了。

 

Ps:我们可以利用Category属性来完成多个联动下拉菜单在一个方法中获取自己数据。

代码如下:

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

 

        switch (category)

        {

            case "city": //定义categorycity的那个CascadingDropDown控件响应

                string selectCommand = "SELECT * FROM [dbo].[tbCountryRegion] WHERE [RegionType] = 1";

                break;

            case "Provinces": //定义categoryProvinces的那个CascadingDropDown控件响应

                string selectCommand = "SELECT * FROM [dbo].[tbCountryRegion] WHERE [RegionType] = 2 AND [RegionID] LIKE '" + categoryValues[1] + "%'";

                break;

            case "Countries": //定义categoryCountries的那个CascadingDropDown控件响应

                string selectCommand = "SELECT * FROM [dbo].[tbCountryRegion] WHERE [RegionType] = 3 AND [RegionID] LIKE '" + categoryValues[1] + "%'";

                break;

            default :

                break ;

        }

 

        SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString);

 

        SqlDataAdapter dbAdaper = new SqlDataAdapter(selectCommand, conn);

 

        DataSet dbset = new DataSet();

        dbAdaper.Fill(dbset, "tbCountryRegion");

 

        DataColumn columnRegionName = dbset.Tables["tbCountryRegion"].Columns["RegionName"];

        DataColumn columnRegionID = dbset.Tables["tbCountryRegion"].Columns["RegionID"];

 

        List<CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>();

       

        foreach (DataRow row in dbset.Tables["tbCountryRegion"].Rows)

        {

            values.Add(new CascadingDropDownNameValue(row[columnRegionName].ToString(), row[columnRegionID].ToString()));

        }

        return values.ToArray();

 

 

 

初学asp.net2.0请多指教。

posted @ 2007-08-07 15:03 灯火阑珊²ºº7 阅读(...) 评论(...) 编辑 收藏