ICallbackEventHandler接口在.net2.0的时候已经有了,以前在做服务端控件的时候就接触过。
最近又跟它打交道了 :),所以整理了一些资料以便自己理解和记忆。
本文主题为:利用ICallbackEventHandler接口实现Ajax效果,利用ICallbackEventHandler接口实现客户端回调,利用ICallbackEventHandler接口实现向服务端无刷新取数据
基础知识:
ICallbackEventHandler接口的定义
namespace System.Web.UI
{
// 摘要:
// 用于指示控件可以作为服务器上的回调事件的目标。
public interface ICallbackEventHandler
{
// 摘要:
// 返回以控件为目标的回调事件的结果。
//
// 返回结果:
// 回调的结果。
string GetCallbackResult();
//
// 摘要:
// 处理以控件为目标的回调事件。
//
// 参数:
// eventArgument:
// 一个字符串,表示要传递到事件处理程序的事件参数。
void RaiseCallbackEvent( string eventArgument);
}
}
测试页面:
ClientCallServerBack.aspx
<! 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 > 测试ICallbackEventHandler </ title >
</ head >
< body >
< form id ="form1" runat ="server" >
< div >
< asp:TextBox ID ="txtValue" runat ="server" TextMode ="MultiLine" > 向服务端发送的数据 </ asp:TextBox >
< input type ="button" id ="btnCallServerData" value ="向服务端请求数据" onclick ="GetDataFromServer()" />
< div style ="border:1px solid #6595d6;width:500px;height:100px;" id ="divMsg" ></ div >
</ div >
</ form >
< script type ="text/javascript" >
function GetDataFromServer()
{
var arg = document.getElementById( " txtValue " ).value;
<%= clientCallBackScript %> ;
}
function ReceiveServerData(data)
{
var receiveData = data;
if (arguments[ 1 ] && typeof arguments[ 1 ] == " function " )
{
var f = arguments[ 1 ].apply( this ,arguments);
// alert(f);
}
alert(arguments.length);
document.getElementById( " divMsg " ).innerHTML = data;
}
function BeforeCallBack()
{
var waitforDealData;
waitforDealData = " (被BeforeCallBack处理过的) " ;
arguments[ 0 ] = waitforDealData;
alert( " BeforeCallBack " + arguments[ 0 ]);
}
</ script >
</ body >
</ html >
后面代码ClientCallServerBack.aspX.cs
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class test_JS_ClientCallServerBack : System.Web.UI.Page,ICallbackEventHandler
{
protected string clientCallBackScript = string .Empty;
string callbackResult = string .Empty;
protected void Page_Load( object sender, EventArgs e)
{
clientCallBackScript = ClientScript.GetCallbackEventReference( this , " arg " , " ReceiveServerData " , " BeforeCallBack " );
}
#region ICallbackEventHandler Members
// 摘要:
// 返回以控件为目标的回调事件的结果。
//
// 返回结果:
// 回调的结果。
public string GetCallbackResult()
{
return callbackResult;
}
//
// 摘要:
// 处理以控件为目标的回调事件。
//
// 参数:
// eventArgument:
// 一个字符串,表示要传递到事件处理程序的事件参数。
public void RaiseCallbackEvent( string eventArgument)
{
callbackResult = eventArgument + " --DateTime: " + DateTime.Now.ToLongTimeString();
}
#endregion
}
首先必须实现接口ICallbackEventHandler的两个成员GetCallbackResult和RaiseCallbackEvent
GetCallbackResult是返回回调的结果,而RaiseCallbackEvent则是处理回调的事件
由上面例子看在Page_Load事件中注册了
clientCallBackScript = ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "BeforeCallBack");
其中arg表示一个参数,当从客户端发送请求的时候其参数就是arg
ReceiveServerData是客户端的一个函数,表示接收到Server端数据后的处理函数
BeforeCallBack,VS中的解释为:启动回调之前在客户端计算的客户端脚本。脚本的结果传回客户端事件处理程序
但我觉得更确切的应该是在客户端中的脚本回调
当在Page_Load中注册了ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "BeforeCallBack");
.net在客户端也自动的注册了相应的脚本:
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTEyNTE2Njk1NzRkZPmg2sGrDMxH4ZJfOHYFpaGVOHHC" />
</div>
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>
<script src="/LotteryAnalysis.Web/WebResource.axd?d=X6NylRAXvpzvfgJ_INjMzQ2&t=633764603620000000" type="text/javascript"></script>
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAgLV1PahCAKU8abfBl+t9Uu57JznFzDwaxuFRHKPWol+" />
<script type="text/javascript">
//<![CDATA[
WebForm_InitCallback();//]]>
</script>
再看看前端代码,当点击按钮的时候激发了GetDataFromServer函数,其中
var arg = document.getElementById("txtValue").value; //-- 是对arg参数的设置
<%=clientCallBackScript %>; //--对服务端回调事件的引用 最终解释的HTML代码为:
WebForm_DoCallback('__Page',arg,ReceiveServerData,BeforeCallBack,null,false);
当执行以上代码的时候会激发服务端ICallbackEventHandler接口中的public void RaiseCallbackEvent(string eventArgument),其中eventArgument则是在客户端中的参数arg
通过RaiseCallbackEvent方法处理后,再通过public string GetCallbackResult()方法返回回调的结果
这时,并调用执行客户端中的ReceiveServerData函数,其arguments有两个,第一个是arg,第二个是BeforeCallBack
通过ICallbackEventHandler接口我们可以很方便的实现DropDownList的三级联动、无刷新数据更新等效果