1.当前要准备好js,下面的代码在网上下的,作者不可考,向这位IT工作者致敬! linkage.js (仅在changeLinkage方法中加入一个SetAssociatedDropDownListValue(element);) 此js库依赖于prototype.js而运行,网上到处有下的
var
Linkage
=
Class.create();
Linkage.prototype
=
{
initialize : function(dataSrc, xmlFile) {
this.dataSrc = dataSrc;
this.xmlFile = xmlFile;
},

dataSrc : "" ,
xmlFile : "" ,
BLANK_SELECT : "-----Select-----" ,

AllMenuArr : new Array() ,

MenuIdArr : new Array() ,

MenuInfoArr : new Array() ,

iDepth : -1 ,

tree : function(dataSrc, Element) {
var node = "";
if(Element.nodeType != 3) {
node = Element;
this.onElement(dataSrc, Element);
}
if(Element.hasChildNodes) {
for(var i=0;i<Element.childNodes.length;i++) {
if (Element.childNodes[i].nodeType != 3) {
this.iDepth++;
this.tree(dataSrc, Element.childNodes[i]);
}
}
}
if(node) {
this.endElement();
}
} ,
onElement : function(dataSrc, ele) {
if ($V(ele, "Value") != null) {
if (this.MenuInfoArr[dataSrc] == null) {
this.MenuInfoArr[dataSrc] = new Array();
}
if (this.MenuInfoArr[dataSrc][this.iDepth] == null) {
this.MenuInfoArr[dataSrc][this.iDepth] = new Array();
}
this.MenuInfoArr[dataSrc][this.iDepth].push(new MenuInfo($V(ele.parentNode, "Value") , $V(ele, "Value") , ($V(ele, "Desc")==null ? $V(ele, "Value") : $V(ele, "Desc"))));
}
} ,

endElement : function() {
this.iDepth--;
} ,
initBlank : function(element) {
element.length = 0;
element.options.add(new Option( this.BLANK_SELECT, "" ));
element.selectedIndex = 0;
} ,
updateAllLast : function(dataSrc, nLevel) {
for(i = nLevel+1; i < this.MenuIdArr[dataSrc].length; i++) {
childNode = $(this.MenuIdArr[dataSrc][i]);
this.initBlank(childNode);
childNode.disabled = true;
}
} ,
initLinkage : function(dataSrc, sValue, nLevel) {
nLevel = Number(nLevel);

if (nLevel > this.MenuIdArr[dataSrc].length || nLevel < 1) {
return;
}

currNode = $(this.MenuIdArr[dataSrc][nLevel-1]);
childNode = $(this.MenuIdArr[dataSrc][nLevel]);

if (currNode.disabled) {
return;
}

for (i=0; i<currNode.options.length; i++) {
if (currNode.options[i].value == sValue) {
currNode.selectedIndex = i;
break;
}
}

if (childNode != null) {
currArr = this.AllMenuArr[dataSrc][nLevel];
this.initBlank(childNode);
for(i=0; i<currArr.length; i++) {
if (currArr[i].parentValue == sValue) {
childNode.options.add(new Option(currArr[i].Desc, currArr[i].Value));
}
}
if ((sValue != '') && (childNode.length > 1)) {
childNode.disabled = false;
} else {
childNode.disabled = true;
}
}

this.updateAllLast(dataSrc, nLevel);
} ,

changeLinkage : function(element) {
SetAssociatedDropDownListValue(element);
this.initLinkage($V(element , "USEDATA"), $F(element), $V(element , "SUBCLASS"));
} ,

setDataSrc : function(dataSrc) {
this.dataSrc = dataSrc;
} ,

setXmlFile : function(xmlFile) {
this.xmlFile = xmlFile;
} ,
init : function() {
var rootEle = loadXML(this.dataSrc, this.xmlFile);
this.tree(this.dataSrc, rootEle);

this.iDepth = -1;

for (i=0; i<this.MenuInfoArr[this.dataSrc].length; i++) {
if (this.AllMenuArr[this.dataSrc] == null) {
this.AllMenuArr[this.dataSrc] = new Array();
}
this.AllMenuArr[this.dataSrc].push(this.MenuInfoArr[this.dataSrc][i]);
}

var selectNodes = document.getElementsByTagName("select");
for (i=0; i<selectNodes.length; i++) {
if ($V(selectNodes[i] , "USEDATA") == this.dataSrc) {
if (this.MenuIdArr[this.dataSrc] == null) {
this.MenuIdArr[this.dataSrc] = new Array();
}
var subClass = Number($V(selectNodes[i] , "SUBCLASS")) - 1;
this.MenuIdArr[this.dataSrc][subClass] = $V(selectNodes[i] , "id");
Event.observe(selectNodes[i], "change", this.changeLinkage.bind(this, selectNodes[i]));
}
}

firstNode = $(this.MenuIdArr[this.dataSrc].first());
this.initBlank(firstNode);
for (i=0; i<this.AllMenuArr[this.dataSrc].first().length; i++) {
firstNode.options.add(new Option(this.AllMenuArr[this.dataSrc].first()[i].Desc, this.AllMenuArr[this.dataSrc].first()[i].Value));
}

this.updateAllLast(this.dataSrc, 0);
}
}


var
MenuInfo
=
Class.create();
MenuInfo.prototype
=
{
initialize : function(sParentValue, sValue, sDesc) {
this.parentValue = sParentValue;
this.Value = sValue;
this.Desc = sDesc;
}
}

function
$V(ele, attr)
{
return ele.getAttribute(attr);
}

function
createXMLDom()
{
if (window.ActiveXObject)
var xmldoc = new ActiveXObject("Microsoft.XMLDOM");
else
if (document.implementation&&document.implementation.createDocument)
var xmldoc = document.implementation.createDocument("","doc",null);
xmldoc.async = false;
xmldoc.preserveWhiteSpace=true;
return xmldoc;
}

function
loadXML(dataSrc, xmlFile)
{
if (xmlFile == null) {
if (window.ActiveXObject) {
return $(dataSrc).documentElement;
} else {
for (i=0; i<$(dataSrc).childNodes.length; i++) {
if ($(dataSrc).childNodes[i].tagName != null) {
return $(dataSrc).childNodes[i];
break;
}
}
}
} else {
var xmlDom = createXMLDom();
try{
xmlDom.load(xmlFile);
}catch(e){
alert("lost xml File");
}
return xmlDom.documentElement;
}
}
2.简单的控件类 必须的属性有USEDATA和Xml,USEDATA可以随便指定,应该是为了页面上有多个联动而设计的,现在没有支持,另一个xml属性用于指定xml格式数据源 ,另外依赖于外部js /Script/linkage.js和/Script/prototype.js
.
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Xml;
using
System.Web.UI.WebControls;
using
System.Web.UI;
using
System.ComponentModel;
using
System.Collections.Specialized;

namespace
Blackant.Controls
{
[DefaultProperty("Value")]
public class AssociatedDropDownList : WebControl, IPostBackDataHandler
{

字段
属性

私有方法
重载事件








IPostBackDataHandler Members
}
}
3简单运用,
<%
@ Page Language="C#"
%>

<%
@ Register Assembly="Blackant.Controls" Namespace="Blackant.Controls" TagPrefix="bawc"
%>

<!
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>

<
script
runat
="server"
>

protected override void OnLoad(EventArgs e)
{
AssociatedDropDownList1.USEDATA = "test";
AssociatedDropDownList1.Xml = @"
<TreeNodes>
<TreeNode Desc=""湖北省"" Value=""HB"">
<TreeNode Desc=""荆门市"" Value=""JM""></TreeNode>
<TreeNode Desc=""武汉市"" Value=""WH"">
<TreeNode Desc=""汉口"" Value=""HK""></TreeNode>
<TreeNode Desc=""武昌"" Value=""WC""></TreeNode>
</TreeNode>
</TreeNode>
<TreeNode Desc=""北京市"" Value=""BJ"">
</TreeNode>
</TreeNodes>
";
base.OnLoad(e);
}

protected void btnSubmit_Click(object sender, EventArgs e)
{
Response.Write("当前选择:"+AssociatedDropDownList1.Value);
}
</
script
>

<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
runat
="server"
>
<
title
>
Untitled Page
</
title
>
</
head
>
<
body
>
<
form
id
="form1"
runat
="server"
>
<
div
>
<
bawc:AssociatedDropDownList
ID
="AssociatedDropDownList1"
runat
="server"
/>
<
asp:Button
runat
="Server"
ID
="btnSubmit"
Text
="查看回传数据"
OnClick
="btnSubmit_Click"
/>
</
div
>
</
form
>
</
body
>
</
html
>






































































































































































































2.简单的控件类 必须的属性有USEDATA和Xml,USEDATA可以随便指定,应该是为了页面上有多个联动而设计的,现在没有支持,另一个xml属性用于指定xml格式数据源 ,另外依赖于外部js /Script/linkage.js和/Script/prototype.js
.

















































































