使用 AJAX 控件工具包实现无刷新页面的级联菜单






4.85/5 (48投票s)
这是一种非常简单且用户友好的 Web 应用程序实现方式,可以在不刷新页面的情况下实现级联菜单。
引言
这是一种非常简单且用户友好的 Web 应用程序实现方式,可以在不刷新页面的情况下实现级联菜单。
您无需了解 AJAX 函数,只需下载 CodePlex 上的 AJAX 控件工具包,然后按照本文所述的步骤操作即可。当您有两个下拉列表并且它们相互关联时,例如在注册页面中的“国家”和“城市”,您想保存用户家乡的信息。当您从第一个下拉列表(国家)中选择一行时,您会期望第二个下拉列表(城市)根据所选行进行过滤,而无需刷新页面。本文展示了一种非常简单且用户友好的解决方案,可用于 Web 应用程序。
背景:什么是 AJAX 控件工具包?
ASP.NET AJAX 控件工具包是一个开源项目,建立在 Microsoft ASP.NET AJAX 框架之上,包含 30 多个控件,可让您轻松创建丰富的交互式网页。如果您想了解更多信息,请在此处访问:此处。
使用代码
第一步是从此处下载 .NET 3.5 或此处下载 .NET 4.0 的 AJAX 控件工具包。
将 AJAX 控件工具包复制到Bin文件夹,右键单击解决方案,选择“添加引用”,然后在“浏览”选项卡中,双击“Bin”文件夹,然后双击“AJAX Control Toolkit”,接着在“生成”菜单中,单击“重新生成”。
数据库
创建一个名为“Db”的数据库。这是创建所需表的查询:
--Create Country Table
CREATE TABLE [dbo].[tblCountry](
[Country] [nvarchar](50) NULL,
[IDC] [int] IDENTITY(1,1) NOT NULL
) ON [PRIMARY]
--Fill Country Table
insert into dbo.tblCountry(Country) values('United States')
insert into dbo.tblCountry(Country) values('United Kingdom')
insert into dbo.tblCountry(Country) values('Spain')
insert into dbo.tblCountry(Country) values('France')
insert into dbo.tblCountry(Country) values('Norway')
--Create City Table
CREATE TABLE [dbo].[tblCity](
[City] [nvarchar](50) NULL,
[CountryID] [int] Not NULL,
[ID] [int] IDENTITY(1,1) NOT NULL
)
ON [PRIMARY]
--Fill City Table
insert into dbo.tblCity(City,CountryID) values('Michigan',1)
insert into dbo.tblCity(City,CountryID) values('New York',1)
insert into dbo.tblCity(City,CountryID) values('London',2)
insert into dbo.tblCity(City,CountryID) values('Barcelona',3)
insert into dbo.tblCity(City,CountryID) values('Madrid',3)
insert into dbo.tblCity(City,CountryID) values('Paris',4)
insert into dbo.tblCity(City,CountryID) values('Kristiansand',5)
insert into dbo.tblCity(City,CountryID) values('Oslo',5)
Visual Studio 2008 - .NET 3.5
创建一个名为 Cascading menus 的网站。创建一个名为CascadingDropDown.aspx的 Web 窗体。在 HTML 视图中,写入以下代码。此部分 C# 和 VB 之间的代码略有不同。如果您是 VB 编码员,请修改第一行页面标签中的两个部分:
- language="VB"
- CodeFile="CascadingDropDown.aspx.vb"
<%@ Page Language="C#" AutoEventWireup="false"
CodeFile="CascadingDropDown.aspx.cs" Inherits="CascadingDropDown" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit"
TagPrefix="ajaxToolkit" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>CascadingDropDown</title>
</head>
<body>
<form id="form1" runat="server">
<ajaxToolkit:ToolkitScriptManager ID="ScriptManager1" runat="server" >
</ajaxToolkit:ToolkitScriptManager>
<div>
<asp:DropDownList ID="ddListCountry" runat="server" Width="170" />
<asp:DropDownList ID="ddListCity" runat="server" Width="170" />
<ajaxToolkit:CascadingDropDown
ID="CascadingCountry"
runat="server"
TargetControlID="ddListCountry"
Category="Country"
PromptText="Please select a Country"
LoadingText="[Loading Country...]"
ServicePath="Cascading.asmx"
ServiceMethod="GetCountries" >
</ajaxToolkit:CascadingDropDown>
<ajaxToolkit:CascadingDropDown
ID="CascadingCity"
runat="server"
TargetControlID="ddListCity"
Category="City"
PromptText="Please select a City"
LoadingText="[Loading City...]"
ServicePath="Cascading.asmx"
ServiceMethod="GetCities"
ParentControlID="ddListCountry" >
</ajaxToolkit:CascadingDropDown>
</div>
</form>
</body>
</html>
对于 VB:创建 Web 服务:解决方案 > 右键单击 > 添加新项 > Web 服务 >。名称:Cascading.asmx。语言:Visual Basic。转到 > App_Code > Cascading.vb。
' (c) Copyright Microsoft Corporation.
' This source is subject to the Microsoft Public License.
' See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
' All other rights reserved.
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Collections.Generic
Imports AjaxControlToolkit
Imports System.Data
Imports System.Data.SqlClient
Imports System.Text.RegularExpressions
Imports System.Collections.Specialized
Imports System.Xml
' To allow this Web Service to be called from script,
' using ASP.NET AJAX, uncomment the following line.
<System.Web.Script.Services.ScriptService()> _
<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class Cascading
Inherits System.Web.Services.WebService
Dim cn As New SqlClient.SqlConnection()
Dim ds As New DataSet
Dim dt As New DataTable
<WebMethod()> _
Public Function GetCountries(ByVal knownCategoryValues As String, _
ByVal category As String) As CascadingDropDownNameValue()
'ADO.Net
Dim strCn As String = "data source=.;Initial Catalog=Db;Integrated Security=True"
cn.ConnectionString = strCn
Dim cmd As New SqlClient.SqlCommand
cmd.Connection = cn
cmd.CommandType = CommandType.Text
cmd.CommandText = "select * from tblCountry"
Try
cn.Open()
cmd.ExecuteNonQuery()
Dim da As New SqlDataAdapter(cmd)
da.Fill(ds)
Catch ex As Exception
Finally
cn.Close()
End Try
dt = ds.Tables(0)
Dim CountryValues As New List(Of CascadingDropDownNameValue)()
For Each row As DataRow In dt.Rows
CountryValues.Add(New CascadingDropDownNameValue(row("Country").ToString(), _
row("IDC").ToString()))
Next
Return CountryValues.ToArray()
End Function
<WebMethod()> _
Public Function GetCities(ByVal knownCategoryValues As String, _
ByVal category As String) As CascadingDropDownNameValue()
Dim kv As StringDictionary = _
CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)
'ContainsKey("Country") is one of property in Ajaxcontroltoolkit
Dim countryId As Integer
If ((Not kv.ContainsKey("Country")) Or _
(Not Int32.TryParse(kv("Country"), countryId))) Then
Return Nothing
End If
'ADO.Net
Dim strCn As String = "data source=.;Initial Catalog=Db;Integrated Security=True"
cn.ConnectionString = strCn
Dim cmd As New SqlClient.SqlCommand
cmd.Connection = cn
'-----I Defined a parameter instead of passing value
' directly to prevent sql injection--------'
cmd.CommandText = "select * from tblCity where CountryID=@myParameter Order by City"
cmd.Parameters.AddWithValue("@myParameter", countryId.ToString())
Try
cn.Open()
cmd.ExecuteNonQuery()
Dim da As New SqlDataAdapter(cmd)
da.Fill(ds)
Catch ex As Exception
Finally
cn.Close()
End Try
dt = ds.Tables(0)
Dim CityValues As New List(Of CascadingDropDownNameValue)()
For Each row As DataRow In dt.Rows
CityValues.Add(New CascadingDropDownNameValue(row("City").ToString(), _
row("ID").ToString()))
Next
Return CityValues.ToArray()
End Function
End Class
对于 C#:Web 服务:解决方案 > 右键单击 > 添加新项 > Web 服务 >。名称:Cascading.asmx。语言:C#。转到 > App_Code > Cascading.cs。
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License.
// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
// All other rights reserved.
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Collections.Generic;
using AjaxControlToolkit;
using System.Data;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
using System.Collections.Specialized;
using System.Xml;
///<summary>
/// Summary description for Cascading
///</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 Cascading : System.Web.Services.WebService {
public Cascading () {
//Uncomment the following line if using designed components
//InitializeComponent();
}
[WebMethod]
public CascadingDropDownNameValue[] GetCountries(string knownCategoryValues,
string category)
{
//ADO.Net
SqlConnection cn =new SqlConnection();
DataSet ds = new DataSet();
DataTable dt = new DataTable();
string strCn = "data source=.;Initial Catalog=Db;Integrated Security=True";
cn.ConnectionString = strCn;
SqlCommand cmd = new SqlCommand();
cmd.Connection = cn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "select * from tblCountry";
try
{
cn.Open();
cmd.ExecuteNonQuery();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
}
catch
{
}
finally
{
cn.Close();
}
dt = ds.Tables[0];
List<CascadingDropDownNameValue> CountryValues =
new List<CascadingDropDownNameValue>();
foreach (DataRow row in dt.Rows)
{
CountryValues.Add(new CascadingDropDownNameValue(
row["Country"].ToString(), row["IDC"].ToString()));
}
return CountryValues.ToArray();
}
[WebMethod]
public CascadingDropDownNameValue[] GetCities(string knownCategoryValues,
string category)
{
StringDictionary kv =
CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);
//'ContainsKey("Country") is one of property in Ajaxcontroltoolkit
int countryId;
countryId = System.Convert.ToInt32(kv["Country"]);
//ADO.Net
SqlConnection cn = new SqlConnection();
DataSet ds = new DataSet();
DataTable dt = new DataTable();
string strCn =
"data source=.;Initial Catalog=Db;Integrated Security=True";
cn.ConnectionString = strCn;
SqlCommand cmd = new SqlCommand();
cmd.Connection = cn;
cmd.CommandType = CommandType.Text;
//-----I Defined a parameter instead of passing value
// directly to prevent sql injection--------//
cmd.CommandText = "select * from tblCity where CountryID=@myParameter Order by City";
cmd.Parameters.AddWithValue("@myParameter", countryId.ToString());
try
{
cn.Open();
cmd.ExecuteNonQuery();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
}
catch
{
}
finally
{
cn.Close();
}
dt = ds.Tables[0];
List<CascadingDropDownNameValue> CityValues =
new List<CascadingDropDownNameValue>();
foreach (DataRow row in dt.Rows)
{
CityValues.Add(new CascadingDropDownNameValue(
row["City"].ToString(), row["ID"].ToString()));
}
return CityValues.ToArray();
}
}
GetCountries
和GetCities
是两个函数,它们接收两个字符串参数:knownCategoryValues
和category
。它们的输出是一个字符串数组:CascadingDropDownNameValue
。在GetCountries
函数中,会填充国家下拉列表:我们连接到数据库并使用 ADO.NET 执行查询,然后在foreach
循环中填充下拉列表。当您选择一行(在上例中,一个国家,如美国)时,knownCategoryValues
将等于“country:1”,这意味着category
是 country,knownCategoryValues
是“1”。1 是数据库中美国的 ID。在GetCities
函数中,城市下拉列表会根据knownCategoryValues
(在本例中为“1”)进行填充和过滤。在 Web 窗体中,我在CascadingCity
中指定了ParentControlID="ddListCountry"
,因此父级是国家,城市将根据国家 ID 进行过滤。此外,我定义了一个参数而不是直接传递值,以防止 SQL 注入。
逐步尝试演示
- 在此处下载 .NET 3.5 或在此处下载 .NET 4.0 下载 AJAX 控件工具包文件。
- 将“AjaxControlToolkit.Dll”文件夹及其所有依赖项(共 18 个对象)复制到您的网站的Bin文件夹中(C:\Cascading\Bin)。
- 右键单击解决方案,选择“刷新”,然后再次右键单击并选择“添加引用”。然后,在“浏览”选项卡中,双击“Bin”文件夹,然后双击“ajaxcontroltoolkit”。在“生成”菜单中 > 单击“重新生成”。
- 创建数据库和表,如上所述,并添加一些具有常见词语的行。
- 创建一个名为CascadingDropDown.aspx的 Web 窗体。在 HTML 视图中,编写一些类似上面的代码。(这应该与我的代码完全相同,因为此部分区分大小写。)
- 创建 Web 服务:解决方案 > 右键单击 > 添加新项 > Web 服务 > 名称:Cascading.asmx。语言:C# 或 VB。转到 > App_Code > Cascading.cs 或 Cascading.vb。
- 如果您是 VB 编码员,请使用 VB 示例,否则请使用 C# 示例。
- 运行程序,选择一个国家,例如美国,您将看到该国家的一些城市列表,例如底特律或纽约市。
反馈
欢迎随时对本文发表反馈;很高兴看到您对这些代码的意见和投票。如果您有任何问题,请随时在此处提问。