在asp.net程序开发的过程中,经常遇到级联 下拉框的应用,如果采用服务器端事件的话,能实现这样的级联下拉框,但是导致烦人的页面刷新。用Ajax技术可以轻松的解决这个问题,实现无刷新的级联下拉框,但是对于一些比较简单,数据量不大的级联下拉框,不用Ajax也能实现。
下面是我实现的一种方法,当然这只能算是旁门左道,但是对于简单的应用,还是可行的。这种方法的思路是,当页面第一次被请求时,把级联下拉框的信息全部发送到客户端,以后下拉框的选择操作,就在客户端完成。虽然这样增加了一点页面第一次打开的数据量,但是如果级联下拉框不太复杂,数据量的增加也不明显,而且页面一旦加载了,就不用再去向服务器请求有关下拉框里的数据。
1、建立一个名为DropDownList.aspx的页面,代码如下:
<%
...
@ Page Language="C#" AutoEventWireup="true" CodeFile="DropDownList.aspx.cs" Inherits="DropDownList"
%>

<!
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
>
简单级联下拉列表
</
title
>

<
script
>
...
<!--
function changeList(classSelect,itemSelect)

...{
//获取第二个下拉列表,清除项目
var secondSelect = document.getElementById(itemSelect);
while(secondSelect.length>0)

...{
secondSelect.options[0] = null;
}
//获取选择的类别的value
var firstSelect = document.getElementById(classSelect);
var classId = firstSelect.options[firstSelect.selectedIndex].value;
//从table中过滤值
var table = document.getElementById("valueTable");
var rowCount = table.rows.length;
for(var i=0;i<rowCount;i++)

...{
var value0 = table.rows[i].cells[0].innerText;
//为第二个下拉列表增加项目
if(value0 == classId)

...{
var value1 = table.rows[i].cells[1].innerText;
secondSelect.options[secondSelect.length] = new Option(value1,value1);
}
}
}
//-->
</
script
>
</
head
>
<
body
>
<
form
id
="form1"
runat
="server"
>
<
div
>
<
strong
>
<
br
/>
简单级联下拉列表
<
br
/>
</
strong
>
<
br
/>
省:
<
asp:DropDownList
ID
="ddl_class"
runat
="server"
Width
="132px"
>
</
asp:DropDownList
>
市:
<
asp:DropDownList
ID
="ddl_item"
runat
="server"
Width
="150px"
>
</
asp:DropDownList
><
br
/>
</
div
>
</
form
>
</
body
>
</
html
>
2、在该页面所对应的.cs文件中加入如下代码:
using
System;
using
System.Data;
using
System.Configuration;
using
System.Collections;
using
System.Web;
using
System.Web.Security;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
System.Web.UI.WebControls.WebParts;
using
System.Web.UI.HtmlControls;

public
partial
class
DropDownList : System.Web.UI.Page

...
{
protected void Page_Load(object sender, EventArgs e)

...{
//调用客户端脚本方法
ddl_class.Attributes.Add("onchange", "changeList('" + this.ddl_class.ClientID + "','" + this.ddl_item.ClientID + "');");

//获取数据集
DataSet ds = GetDataSet();

//设置两个下拉列表初始化时的下拉项目
for (int i = 0; i < ds.Tables[0].Rows.Count;i++ )

...{
ListItem item = new ListItem(ds.Tables[0].Rows[i][1].ToString(),ds.Tables[0].Rows[i][0].ToString());
ddl_class.Items.Add(item);
}
ddl_class.SelectedIndex = 0;

DataView view = ds.Tables[1].DefaultView;
view.RowFilter = "relId ='0'";
for (int i = 0; i < view.Count; i++)

...{
ListItem item = new ListItem(view[i][1].ToString());
ddl_item.Items.Add(item);
}
ddl_item.SelectedIndex = 0;

//向客户端发送备选的项目表
CreatTable(ds.Tables[1]);
}

private void CreatTable(DataTable table)

...{
Table Table1 = new Table();
Table1.ID = "valueTable";

//通过css隐藏table,不在页面显示
//注意不能用Table1.Visible = false;
//如果这样,则table在页面上生成后,是一个<input type="hidden">
Table1.Attributes.Add("style", "display : none");

for (int i = 0; i < table.Rows.Count; i++)

...{
TableRow r = new TableRow();
for (int j = 0; j < table.Columns.Count; j++)

...{
TableCell c = new TableCell();
c.Controls.Add(new LiteralControl(table.Rows[i][j].ToString()));
r.Cells.Add(c);
}
Table1.Rows.Add(r);
}
this.Controls.Add(Table1);
}

//获取数据集,可以换成从数据库中读取的
private DataSet GetDataSet()

...{
DataTable table1 = new DataTable();
table1.Columns.Add("id", typeof(int));
table1.Columns.Add("name", typeof(string));

DataRow row = table1.NewRow();
row[0] = 0;
row[1] = "黑龙江省";
table1.Rows.Add(row);

row = table1.NewRow();
row[0] = 1;
row[1] = "吉林省";
table1.Rows.Add(row);

row = table1.NewRow();
row[0] = 2;
row[1] = "辽宁省";
table1.Rows.Add(row);

DataTable table2 = new DataTable();
table2.Columns.Add("relId", typeof(int));
table2.Columns.Add("name", typeof(string));

//0
row = table2.NewRow();
row[0] = 0;
row[1] = "哈尔滨市";
table2.Rows.Add(row);

row = table2.NewRow();
row[0] = 0;
row[1] = "大庆市";
table2.Rows.Add(row);

row = table2.NewRow();
row[0] = 0;
row[1] = "齐齐哈尔市";
table2.Rows.Add(row);

row = table2.NewRow();
row[0] = 0;
row[1] = "佳木斯市";
table2.Rows.Add(row);

row = table2.NewRow();
row[0] = 0;
row[1] = "鹤岗市";
table2.Rows.Add(row);

row = table2.NewRow();
row[0] = 0;
row[1] = "牡丹江市";
table2.Rows.Add(row);

//1
row = table2.NewRow();
row[0] = 1;
row[1] = "长春市";
table2.Rows.Add(row);

row = table2.NewRow();
row[0] = 1;
row[1] = "吉林市";
table2.Rows.Add(row);

row = table2.NewRow();
row[0] = 1;
row[1] = "松源市";
table2.Rows.Add(row);

row = table2.NewRow();
row[0] = 1;
row[1] = "四平市";
table2.Rows.Add(row);

row = table2.NewRow();
row[0] = 1;
row[1] = "通化市";
table2.Rows.Add(row);

row = table2.NewRow();
row[0] = 1;
row[1] = "辽源市";
table2.Rows.Add(row);

//2
row = table2.NewRow();
row[0] = 2;
row[1] = "沈阳市";
table2.Rows.Add(row);

row = table2.NewRow();
row[0] = 2;
row[1] = "大连市";
table2.Rows.Add(row);

row = table2.NewRow();
row[0] = 2;
row[1] = "葫芦岛市";
table2.Rows.Add(row);

row = table2.NewRow();
row[0] = 2;
row[1] = "鞍山市";
table2.Rows.Add(row);

row = table2.NewRow();
row[0] = 2;
row[1] = "抚顺市";
table2.Rows.Add(row);

row = table2.NewRow();
row[0] = 2;
row[1] = "本溪市";
table2.Rows.Add(row);

DataSet ds = new DataSet();
ds.Tables.Add(table1);
ds.Tables.Add(table2);
return ds;
}
}
这样一个简单的级联下拉框就实现了。在这个例子中,为了说明的方便,数据是直接在页面中构建出来的,其实这些数据也可以放在数据库中。这样维护起来就能方便些,也比较灵活些。当然,正如前面所言,这只是旁门左道而已。其中主要用到的知识有:asp.net后台代码动态生成table、JavaScript操作table、JavaScript操作客户端html代码中的Select等。