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

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