記得以前做asp的時(shí)候,常會(huì)碰到下拉框多級(jí)聯(lián)動(dòng),比如說(shuō)在注冊(cè)的時(shí)候,需要選擇省和城市,這就需要二級(jí)聯(lián)動(dòng),那個(gè)時(shí)候一個(gè)普遍的做法就是利用 javascript腳本來(lái)實(shí)現(xiàn),先把數(shù)據(jù)從數(shù)據(jù)庫(kù)中讀取出來(lái),放到j(luò)avascript的數(shù)組中,在下拉框的onchange事件觸發(fā)時(shí),就可以直接從 javascript的數(shù)組中讀取想要的數(shù)據(jù)。后來(lái)在asp.net 1.0中開(kāi)發(fā)時(shí),這種方法也通用,但如果要多級(jí)的話(huà),有一個(gè)很大的缺點(diǎn),就是它需要把數(shù)據(jù)一次性全部讀到j(luò)avascript的數(shù)組中,如果數(shù)據(jù)非常龐大 的話(huà),這部分開(kāi)銷(xiāo)是很大的,有時(shí)候不把數(shù)據(jù)放到數(shù)據(jù)中中,而是直接寫(xiě)在javascript中,這樣不易于維護(hù),而且代碼也太長(zhǎng),如果要開(kāi)發(fā)可以無(wú)限級(jí)聯(lián) 的話(huà),那更是比較頭痛。自從asp,net 2.0問(wèn)世后,開(kāi)始學(xué)習(xí)新技術(shù),發(fā)現(xiàn)asp,net2.0不僅在控件上,功能上都產(chǎn)生了大變化,而且在對(duì)javascript客戶(hù)腳本的調(diào)用功能也更加強(qiáng) 大了,特別是出現(xiàn)了ajax功能,即客戶(hù)端回調(diào)功能(當(dāng)然這只是一個(gè)小小的ajax功能,如果要實(shí)現(xiàn)功能更強(qiáng)大的無(wú)刷新可看atlas),利用這個(gè)特性可 以很方便的開(kāi)發(fā)現(xiàn)無(wú)限級(jí)聯(lián)動(dòng)的下拉框效果。
1、先在數(shù)據(jù)庫(kù)里建立相應(yīng)的數(shù)據(jù)表如下:
2、建立讀取數(shù)據(jù)表的函數(shù),這里就不寫(xiě)出來(lái)了,我想每個(gè)人都會(huì)有不同的方法去實(shí)現(xiàn)這一功能。
3、接下來(lái),我們就可以進(jìn)行頁(yè)面設(shè)置了,我們先做一個(gè)二級(jí)聯(lián)動(dòng)的效果,在頁(yè)面上放置二個(gè)下拉框控件,上面一個(gè)為T(mén)estDropDownList,下面一 個(gè)為Item1,再加入一個(gè)objectdatasource控件,用來(lái)讀取parentId為0的所有記錄綁定到TestDropDownList下拉 框中,如下圖:
如果要使用客戶(hù)端回調(diào),必須要實(shí)現(xiàn)System.Web.UI.ICallbackEventHandler接口。
1public partial class Test : System.Web.UI.Page , System.Web.UI.ICallbackEventHandler
2{
該接口下面,有二個(gè)方法:
a)、void System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent(string eventArguent)
該方法接收客戶(hù)端傳過(guò)來(lái)的參數(shù)enentArguent,這個(gè)參數(shù)好象只能是string型,并且沒(méi)有返回值,我們可以根據(jù)傳過(guò)來(lái)的參數(shù),來(lái)執(zhí)行相應(yīng)的 功能,在這里我們不能對(duì)頁(yè)面進(jìn)行重新綁定等操作,但能夠跟數(shù)據(jù)庫(kù)進(jìn)行交互操作,如讀取、刪除、插入等操作,在本文的例子中,這里從客戶(hù)端傳過(guò)來(lái)的是 parentId的值,再?gòu)臄?shù)據(jù)庫(kù)中讀取parentId為相應(yīng)值的所有記錄,具體代碼如下:
1void System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent(string eventArguent)
2 {
3 DataSet ds = new GetData().TestByParentId(Convert.ToInt32(eventArguent));
4 foreach(DataRow row in ds.Tables[0].Rows)
5 {
6 if (result.Equals(string.Empty))
7 {
8 result = row["pkId"] + "@" + row["name"].ToString();
9 }
10 else
11 {
12 result = result + "," + row["pkId"] + "@" + row["name"].ToString();
13 }
14 }
15 }
在這里,通過(guò)TestByParentId(Convert.ToInt32(enentArguent))函數(shù)讀到相應(yīng)數(shù)據(jù),并把得到的數(shù)據(jù)作了一些處理,這個(gè)為什么要這樣做,請(qǐng)繼續(xù)往下看。這里的result為string型變量。
b)、string System.Web.UI.ICallbackEventHandler.GetCallbackResult()
這是第二個(gè)方法,該方法沒(méi)有參數(shù),返回只能返回string型。這個(gè)方法是用來(lái)數(shù)據(jù)回調(diào)的,上面那個(gè)方法接收客戶(hù)端傳過(guò)來(lái)的參數(shù),進(jìn)行處理后,還要把處 理后的我們想要的數(shù)據(jù)傳回到客戶(hù)端去執(zhí)行,才會(huì)有用。這里我們也看到了,由于該方法只能返回string型,而在下拉框必須有二個(gè)值,一個(gè)是 DataValue,另一個(gè)是DataText,所以在上面的方法中,通過(guò)@符號(hào),把這二個(gè)值合在一起,便于在客戶(hù)端程序中進(jìn)行分離。這個(gè)方法功能很簡(jiǎn) 單,就是把result返回即可,如下:
1string System.Web.UI.ICallbackEventHandler.GetCallbackResult()
2 {
3 return result;
4 }
現(xiàn)在我們實(shí)現(xiàn)了System.Web.UI.ICallbackEventHandler接口下的全部方法,接下來(lái)我們就可以來(lái)寫(xiě)客戶(hù)端的程序了,用 javascript來(lái)實(shí)現(xiàn)。這里主要也有二個(gè)方法,第一個(gè)方法用來(lái)接受下拉框控件的onchange事件觸發(fā)響應(yīng),另一個(gè)用來(lái)接收string System.Web.UI.ICallbackEventHandler.GetCallbackResult()方法傳遞過(guò)來(lái)的result值,并做 相應(yīng)處理,把數(shù)據(jù)綁定到第二個(gè)下拉框中去,實(shí)現(xiàn) 二級(jí)聯(lián)動(dòng)。主要代碼如下
a)、第一個(gè)方法
1 function CallServer(input, context)
2 {
3 context.length=0;
4 context.options[context.length]=new Option("數(shù)據(jù)讀取中","0");
5
6 arg = input.value;
7 <%=callback %>
8 }
這里有二個(gè)參數(shù),input是用來(lái)觸發(fā)onchange的下拉框控件名稱(chēng),context是要級(jí)聯(lián)的下拉框名稱(chēng),這里在數(shù)據(jù)還沒(méi)有綁定之前,級(jí)聯(lián)下拉框 顯示“數(shù)據(jù)讀取中...”字樣。arg接收input下拉框的值,這個(gè)值以后是傳遞到上面的eventArguent參數(shù)中去,其中的<%= callback%>我們下面再介紹。
b)、第二個(gè)方法
1 function ReceiveServerData(result, context)
2 {
3 context.length=0;
4 var arrData = result.split(",");
5 for (var i = 0; i < arrData.length; i++)
6 {
7 var data = arrData[i].split("@");
8 context.options[context.length]=new Option(data[1],data[0]);
9 }
10
11 }
這里也有二個(gè)參數(shù),其中result,就是接收上面講到的result值,而context同第一個(gè)方法的context。這里通過(guò)js的split方法,把數(shù)據(jù)進(jìn)行處理,再綁定到context控件中去,通過(guò)這個(gè)就可以在第二個(gè)下拉框中出現(xiàn)相應(yīng)的值了。
做到這里基本上已經(jīng)大功告成了,不過(guò)還有最后一步,這也是最重要的一步,我們現(xiàn)在做的只是客戶(hù)端歸客戶(hù)端,服務(wù)器方法歸服務(wù)器方法,那么怎么樣把這二個(gè) 聯(lián)系起來(lái)呢,這也是實(shí)現(xiàn)客戶(hù)端回調(diào)的關(guān)鍵部分,這里需要使用Page.ClientScript.GetCallbackEventReference方 法,下面是摘自MSDN2上的對(duì)ClientScript.GetCallbackEventReference(……)的詳細(xì)說(shuō)明。
public string GetCallbackEventReference (Control control,string argument,string clientCallback,string context)
參數(shù):
參數(shù) 作用
control 處理客戶(hù)端回調(diào)的服務(wù)器 Control。該控件必須實(shí)現(xiàn) ICallbackEventHandler 接口并提供 RaiseCallbackEvent 方法。
argument 從客戶(hù)端腳本傳遞一個(gè)參數(shù)到服務(wù)器端的RaiseCallbackEvent 方法。
clientCallback 一個(gè)客戶(hù)端事件處理程序的名稱(chēng),該處理程序接收服務(wù)器端事件返回的結(jié)果。
context 啟動(dòng)回調(diào)之前在客戶(hù)端的客戶(hù)端腳本信息。腳本的結(jié)果傳回給客戶(hù)端事件處理程序。
返回值 調(diào)用客戶(hù)端回調(diào)的客戶(hù)端函數(shù)的名稱(chēng)。
下面是ClientScriptManager.GetCallbackEventReference 方法的重載列表
名稱(chēng) 說(shuō)明
ClientScriptManager.GetCallbackEventReference (Control, String, String, String) 獲取一個(gè)對(duì)客戶(hù)端函數(shù)的引用;調(diào)用該函數(shù)時(shí),將啟動(dòng)一個(gè)對(duì)服務(wù)器端事件的客戶(hù)端回調(diào)。此重載方法的客戶(hù)端函數(shù)包含指定的控件、參數(shù)、客戶(hù)端腳本和上下文。
ClientScriptManager.GetCallbackEventReference (Control, String, String, String, Boolean) 獲取一個(gè)對(duì)客戶(hù)端函數(shù)的引用;調(diào)用該函數(shù)時(shí),將啟動(dòng)一個(gè)對(duì)服務(wù)器端事件的客戶(hù)端回調(diào)。此重載方法的客戶(hù)端函數(shù)包含指定的控件、參數(shù)、客戶(hù)端腳本、上下文和 布爾值。
ClientScriptManager.GetCallbackEventReference (Control, String, String, String, String, Boolean) 獲取一個(gè)對(duì)客戶(hù)端函數(shù)的引用;調(diào)用該函數(shù)時(shí),將啟動(dòng)一個(gè)對(duì)服務(wù)器端事件的客戶(hù)端回調(diào)。此重載方法的客戶(hù)端函數(shù)包含指定的控件、參數(shù)、客戶(hù)端腳本、上下文、 錯(cuò)誤處理程序和布爾值。
ClientScriptManager.GetCallbackEventReference (String, String, String, String, String, Boolean) 獲取一個(gè)對(duì)客戶(hù)端函數(shù)的引用;調(diào)用該函數(shù)時(shí),將啟動(dòng)一個(gè)對(duì)服務(wù)器端事件的客戶(hù)端回調(diào)。此重載方法的客戶(hù)端函數(shù)包含指定的目標(biāo)、參數(shù)、客戶(hù)端腳本、上下文、 錯(cuò)誤處理程序和布爾值。
主要實(shí)現(xiàn)如下:
在page_load里加入下面語(yǔ)句
1callback = Page.ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");
其中,arg就是用來(lái)從客戶(hù)端傳遞參數(shù),最終傳到enentArguent中,ReceiveServerData是一個(gè)客戶(hù)端方法,用來(lái)接收服務(wù)器端回調(diào)過(guò)來(lái)的數(shù)據(jù)。
再把callback這個(gè)字符串放在第一個(gè)客戶(hù)端方法下面(請(qǐng)看上面的第一個(gè)客戶(hù)端方法)
這個(gè)完成后,我們只要把第一個(gè)下拉框的onchange客戶(hù)端事件加入就可以了,在page_load里加入
1TestDropDownList.Attributes["onchange"] = "javascript:CallServer(TestDropDownList , Item1)";
做完所有這些,程序應(yīng)該能夠正常動(dòng)行了
現(xiàn)在二級(jí)聯(lián)動(dòng)已經(jīng)成功,那怎么能夠?qū)崿F(xiàn)多級(jí)的呢,其實(shí)大家只要仔細(xì)的看一下,就不難發(fā)現(xiàn),當(dāng)我觸到一個(gè)下拉框的onchange事件,通過(guò) callServer讀取值,再通過(guò)<%callback%>來(lái)啟動(dòng) void System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent(string eventArguent)這個(gè)方法,把數(shù)據(jù)處理后,通過(guò)string System.Web.UI.ICallbackEventHandler.GetCallbackResult()方法返回,再由 ReceiveServerData客戶(hù)端來(lái)把數(shù)據(jù)綁定到相應(yīng)原下拉框中,而這里的二個(gè)互動(dòng)的下拉框都是通過(guò)參數(shù)來(lái)傳遞的, TestDropDownList.Attributes["onchange"] = "javascript:CallServer(TestDropDownList , Item1)"; 這樣的話(huà),我們可以改變這里傳遞的控件參數(shù)名,就可以重復(fù)利用這四個(gè)方法,也就是這樣就可以實(shí)現(xiàn),無(wú)限級(jí)聯(lián)動(dòng)。我們?cè)偌尤胍粋€(gè)下拉框, 取名Item2,我們只要在page_load中加入如下語(yǔ)句即可:
1Item1.Attributes["onchange"] = "javascript:CallServer(Item1 , Item2)";
就就可以三級(jí)聯(lián)動(dòng)了,如果要四級(jí),五級(jí),只要加入下應(yīng)的下拉框,并在page_load中加入相應(yīng)的onchange事件觸發(fā),就可以實(shí)現(xiàn)了
不過(guò)這種方法目前還有一個(gè)很大的二個(gè)缺點(diǎn):
1、那就是當(dāng)?shù)谝粋€(gè)選擇后,第二個(gè)下拉框會(huì)出現(xiàn)相應(yīng)的值,而第三個(gè)以及下面的幾個(gè)不會(huì)變,只有再選擇第二個(gè)下拉框的值后,第三個(gè)才會(huì)改變
2、由于1的問(wèn)題,導(dǎo)致如果第二個(gè)下拉框中只有一個(gè)值,那么第三個(gè)以及以下幾個(gè)都不能發(fā)生改變了,不知道大家有沒(méi)有好的解決方法,我相信應(yīng)該有解決的方法的。
由于本人水平有限,可能有不當(dāng)之處,希望大家能夠指正,謝謝!
利用ASP.NET 2.0的客戶(hù)端回調(diào)功能制作下拉框無(wú)限級(jí)聯(lián)動(dòng)
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
