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

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