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;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的三级联动、无刷新数据更新等效果