使用 CascadingDropDown 连接数据库






4.74/5 (13投票s)
如何使用 CascadingDropDown 和 AjaxToolKit

引言
CascadingDropDownExtender 是最流行的 AjaxControlToolkit 扩展器之一
工具包附带的示例演示了 CascadingDropDown 与 XML 数据存储的使用。一个常见的问题是如何将其与数据库一起使用
背景
我最近发现自己需要处理一个案例,其中我有三个下拉列表,并且需要在它们之间建立级联关系
使用 CascadingDropDown 扩展器确实使这件事变得容易,但我还有额外的要求,城市下拉列表应该通过大陆和国家/地区进行过滤。因此,当选择一个大陆时,所有匹配的国家/地区类型以及所有匹配的城市都会被填充。选择国家/地区时,城市列表应仅包含该国家/地区的城市。
起初,我尝试从城市到大陆简单地设置一个新的扩展器,这可行,直到我从国家/地区列表中选择一个值,之后尝试取消选择一个值将使我得到一个禁用的下拉列表。
注意:要使用此工具包组件,您应该安装 AJAX Control Toolkit
从 The Official Microsoft ASP.NET Site 下载 AJAX Control Toolkit
将 AJAX Toolkit 控件添加到 Visual Studio 工具箱
在 Visual Studio(或 Visual Web Developer Express)中,右键单击工具箱并选择添加选项卡
给选项卡一个名称
展开刚刚创建的选项卡,然后右键单击该部分并选择“选择项”。
现在,AJAX Toolkit 控件将出现在您的工具箱中
Using the Code
在 default.aspx 页面中,添加一些下拉列表
<dropdownlist id="MainLanddd" runat="server" width="149px" datasourceid="ods_Continent" datatextfield="Name" datavaluefield="Id" /> <asp:DropDownList ID="MainLanddd" runat="server" Width="149px" DataSourceID="ods_Continent" DataTextField="Name" DataValueField="Id"> </asp:DropDownList> < <asp:ObjectDataSource ID="ods_Continent" runat="server" OldValuesParameterFormatString="original_{0}" SelectMethod="GetContinentByParentId" TypeName="dsContinentTableAdapters.ContinentTableAdapter"> <SelectParameters> <asp:Parameter DefaultValue="0" Name="ParentId" Size="4" Type="Int32" /> </SelectParameters> </asp:ObjectDataSource> <asp:DropDownList ID="Countrydd" runat="server" Width="150px"> </asp:DropDownList> <asp:DropDownList ID="Citydd" runat="server" Width="150px"> </asp:DropDownList>
现在,在 ASPX 页面顶部,为对工具包的引用注册一个前缀
<%@ Register assembly="AjaxControlToolkit" namespace="AjaxControlToolkit" tagprefix="cc1" %> <%@ Register assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" namespace="System.Web.UI" tagprefix="asp" %>
然后添加扩展器本身
<cc1:CascadingDropDown ID="CascadingCountry" Category="MainLand" runat="server" ServicePath="MainLandService.asmx" ServiceMethod="GetCountryId" TargetControlID="Citydd" ParentControlID="Countrydd"> </cc1:CascadingDropDown> <cc1:CascadingDropDown ID="CascadingContinent" Category="MainLand" runat="server" ServicePath="MainLandService.asmx" ServiceMethod="GetContinentId" TargetControlID="Countrydd" ParentControlID="MainLanddd"> </cc1:CascadingDropDown>
在运行时,扩展器将回调到我们指定的 Web 服务(该服务使用 System.Web.Script.Services.ScriptService 属性进行修饰)。在该 Web 服务中,它期望一个具有以下签名的 WebMethod(请注意,参数名称必须匹配工具)
[WebMethod] CascadingDropDownNameValue[] GetColorsForModel( knownCategoryValues,string category)
knownCategoryValues 参数将返回一个字符串,其中包含当前选定的类别值,以及要检索值的类别。例如,如果扩展器正在填充“大陆”字段,则将传递“国家/地区”和“城市”字段的值,以及“颜色”以指定要返回值的字段。
CascadingDropDown 类有一个用于解包类别值的辅助方法
CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);
此方法将返回一个 StringDictionary,其中包含当前选定值的名称/值对。因此,假设您有一个包含制造商、型号和颜色信息的数据库表,并且您正在通过 DataSet 访问该数据库,您已向该 DataSet 添加了用于获取每组值的方法。
用于获取给定型号可用颜色的 Web 方法如下所示
StringDictionary categoryValues = AjaxControlToolkit.CascadingDropDown.ParseKnownCategoryValuesString( knownCategoryValues); int countryID = Convert.ToInt32(categoryValues["MainLand"]); List<CascadingDropDownNameValue> cascadingValues = new List<CascadingDropDownNameValue>(); dsContinentTableAdapters.ContinentTableAdapter _continentAdapter = new dsContinentTableAdapters.ContinentTableAdapter(); foreach (DataRow _row in _continentAdapter.GetContinentByParentId(countryID)) { cascadingValues.Add(new CascadingDropDownNameValue(_row["Name"].ToString(), _row["ID"].ToString())); } return cascadingValues.ToArray();
因此,返回这些值很简单。请注意,这些值以 CascadaingDropDownNameValue 结构的数组形式返回。此结构还包括一个 isDefaultValue 布尔字段,允许指定首次显示列表时应选择哪个值。
现在让我们连接我们的扩展器
<cc1:CascadingDropDown ID="CascadingCountry" Category="MainLand" runat="server" ServicePath="MainLandService.asmx" ServiceMethod="GetCountryId" TargetControlID="Citydd" ParentControlID="Countrydd"> </cc1:CascadingDropDown> <cc1:CascadingDropDown ID="CascadingContinent" Category="MainLand" runat="server" ServicePath="MainLandService.asmx" ServiceMethod="GetContinentId" TargetControlID="Countrydd" ParentControlID="MainLanddd"> </cc1:CascadingDropDown>
完成 Web 服务方法后,您的级联下拉列表就完成了!
关注点
Notice
在您的 Web Config 中,您必须添加此标签
<configuration> <configSections> <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"> <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"> <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/> <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"> <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="Everywhere"/> <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/> <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/> </sectionGroup> </sectionGroup> </sectionGroup> </configSections> <appSettings/> <connectionStrings> <add name="ModelCascadingConnectionString" connectionString="Data Source=SOFTWAR\BIZ;Initial Catalog=ModelCascading; User ID=sa;Password=123" providerName="System.Data.SqlClient"/> </connectionStrings> <system.web> <!-- Set compilation debug="true" to insert debugging symbols into the compiled page. Because this affects performance, set this value to true only during development. --> <pages> <controls> <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> </controls> </pages> <compilation debug="true"> <assemblies> <add assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> <add assembly="System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/> <add assembly="System.Web.Extensions.Design, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> <add assembly="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> </assemblies> </compilation> <!-- The <authentication> section enables configuration of the security authentication mode used by ASP.NET to identify an incoming user. --> <authentication mode="Windows"/> <!-- The <customErrors> section enables configuration of what to do if/when an unhandled error occurs during the execution of a request. Specifically, it enables developers to configure html error pages to be displayed in place of a error stack trace. <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm"> <error statusCode="403" redirect="NoAccess.htm" /> <error statusCode="404" redirect="FileNotFound.htm" /> </customErrors> --> <httpHandlers> <remove verb="*" path="*.asmx"/> <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/> </httpHandlers> <httpModules> <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> </httpModules> </system.web> <system.web.extensions> <scripting> <webServices> <!-- Uncomment this line to customize maxJsonLength and add a custom converter --> <!-- <jsonSerialization maxJsonLength="500"> <converters> <add name="ConvertMe" type="Acme.SubAcme.ConvertMeTypeConverter"/> </converters> </jsonSerialization> --> <!-- Uncomment this line to enable the authentication service. Include requireSSL="true" if appropriate. --> <!-- <authenticationService enabled="true" requireSSL = "true|false"/> --> <!-- Uncomment these lines to enable the profile service. To allow profile properties to be retrieved and modified in ASP.NET AJAX applications, you need to add each property name to the readAccessProperties and writeAccessProperties attributes. --> <!-- <profileService enabled="true" readAccessProperties="propertyname1,propertyname2" writeAccessProperties="propertyname1,propertyname2" /> --> </webServices> <!-- <scriptResourceHandler enableCompression="true" enableCaching="true" /> --> </scripting> </system.web.extensions> <system.webServer> <validation validateIntegratedModeConfiguration="false"/> <modules> <add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> </modules> <handlers> <remove name="WebServiceHandlerFactory-Integrated"/> <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> </handlers> </system.webServer> </configuration>