ASP.NET 2.0 正式版中callback的一些变化+使用示例
2005-11-29 17:01
597 查看
本文来自 出走的影子 http://jackielin.cnblogs.com/archive/2005/11/27/callback.html
可能你觉得callback很弱,AJAX才够强。其实网上大多数callback的示例代码都是不太正确的(包括MSDN)。这里提供了一种不同的使用callback的方法。只用很少的javascript就实现了一个联级下拉框。你会发现:轻量级的callback其实也很好用。
在这里我有两个DropDownList,ddlCategory和ddlProduct。要求ddlCategory变化后ddlProduct无刷新的填充新的项目。
要使用Callback首先要继承ICallbackEventHandler接口:
public partial class Callback : Page, ICallbackEventHandler 或:
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
正式版的ICallbackEventHandler要实现以下两个方法:
string GetCallbackResult ()
void RaiseCallbackEvent (string eventArgument)
eventArgument现在改为由RaiseCallbackEvent接收,而不是由GetCallbackResult直接接受了。目的是为了让你可以在RaiseCallbackEvent中做一些初始化操作,这点在编写支持callback的控件时特别有用,有兴趣的话你可以参考GridView和DetailView中RaiseCallbackEvent的代码。在这里我只使用最简单的方式,把eventArgument存到一个私有成员中:
private string _callbackEventArgument;
protected virtual void RaiseCallbackEvent(string eventArgument)
{
this._callbackEventArgument = eventArgument;
}
在客户端触发callback需要使用到GetCallbackEventReference,正式版中的GetCallbackEventReference位于Page.ClientScript下。ClientScript是2.0中Page的一个新增成员,专门用于处理客户端教本(javascript),它是一个实例化的ClientScriptManager。
<script type="text/javascript">
function CallServer(arg, context)
{
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context")%>;
}
function ReceiveServerData(result, context)
{
...
}
</script>
protected void Page_Load(object sender, EventArgs e)
{
ddlCategory.Attributes.Add("onchange", "CallServer(....)");
}
在这里我使用了一个javascript函数CallServer来包装callback的触发,当然你也可把它直接挂到onchange或其他客户端事件上。不过用一个函数来包装的话,可以很方便的在callback前后做一些其他操作,下面我就会用到。
不知道你有没有发觉,我们传给callback两个参数:arg和context,但是RaiseCallbackEvent只得到一个(arg),另一个参数context会给原封不动的传给ReceiveServerDate。这个context到底有什么用呢?甚至连MSDN里的代码也没有很正确的使用这个参数。可能你觉得callback很弱,只传入一个string(arg)传出一个string(result),还要编写大量的javascript代码才能实现想要的功能。其实,只要正确使用上面那个context参数就可以用很少的javascript实现很理想的功能。
首先,我们拆分一下arg,把我们要调用的服务端方法放进去:
ddlCategory.Attributes.Add("onchange", "CallServer('FillProduct|'+this.value, ...)");
然后用反射在服务器端调用这个方法(FillProduct):
public string GetCallbackResult()
{
string[] parts = _callbackEventArgument.Split('|');
return this.GetType().GetMethod(parts[0]).Invoke(this, new objcet[]{parts[1]}) ;
}
我们来看看FillProduct会返回些什么:
public string FillProduct(string categoryID)
{
ddlCategory.SelectedValue = categoryID;
ddlProduct.DataBind();
StringWriter writer1 = new StringWriter(CultureInfo.InvariantCulture);
HtmlTextWriter writer2 = new HtmlTextWriter(writer1);
ddlProduct.RenderControl(writer2);
writer2.Flush();
writer2.Close();
return writer1.ToString();
}
你可以看到,我把需要更新的ddlProduct整个重新Render后传回来了,也就是说要用新生成的ddlProduct的HTML替换原来的ddlProduct的HTML。怎么做到这一点呢?context参数要出马了:
<script type="text/javascript">
function CallServer(arg, context)
{
[b]context.innerHTML [/b]= "Loading
![](http://www.cnblogs.com/Images/dot.gif)
";
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context")%>;
}
function ReceiveServerData(result, context)
{
[b]context.innerHTML [/b]= result;
}
</script>
.....
<asp:DropDownList ID="ddlCategory" runat="server" DataSourceID="SqlDataSource1"
DataTextField="CategoryName" DataValueField="CategoryID" AppendDataBoundItems="True" >
<asp:ListItem Value="">- Select Category -</asp:ListItem>
</asp:DropDownList>
<span id="_span1">
<asp:DropDownList ID="ddlProduct" runat="server" DataSourceID="SqlDataSource2"
DataTextField="ProductName" AppendDataBoundItems="True">
<asp:ListItem Value="">- Select Product -</asp:ListItem>
</asp:DropDownList>
</span>
protected void Page_Load(object sender, EventArgs e)
{
ddlCategory.Attributes.Add("onchange", "CallServer('FillProduct|'+this.value, _span1)");
} 原来我把要更新的ddlProduct放在_span1里,context就是用来传递这个_span1的。只要用新生成的HTML填充这个_span1,ddlProduct的更新就OK了。这样我们就很轻松的完成了一个无刷新的联级下拉框。
需要注意的是,要在页面提交(postback)后取得这个ddlProduct的值,需要使用
Request.Form[ddlProduct.UniqueID]
因为viewstate并没有被更新。
在下面的完整代码里我还做了如下两件事,以提高代码的复用性: 对_callbackEventArgument稍加处理,以便调用任意多个参数的方法(FillProduct只有一个参数)
提取了FillProduct中Rander Control的那部分,以便于其他方法也可以使用。(这项操作用VS2005的Refactor很容易就完成了
其实你可以把这两部分整理到一个CallbackHelp类中,这样复用性就更高了。
Enjoy it.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Callback.aspx.cs" Inherits="Callback" %>
<!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">
<script type="text/javascript">
function CallServer(arg, context)
{
context.innerHTML = "Loading
![](http://www.cnblogs.com/Images/dot.gif)
";
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context") %>;
}
function ReceiveServerData(result, context)
{
context.innerHTML = result;
}
</script>
<head runat="server">
<title>Callback</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString1 %>"
SelectCommand="SELECT [CategoryID], [CategoryName] FROM [Categories]">
</asp:SqlDataSource>
<asp:SqlDataSource ID="SqlDataSource2" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString1 %>"
SelectCommand="SELECT [ProductID], [ProductName] FROM [Products] WHERE ([CategoryID] = @CategoryID)">
<SelectParameters>
<asp:ControlParameter ControlID="ddlCategory" Name="CategoryID"
PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>
<div id="_div1" runat="server">
<asp:DropDownList ID="ddlCategory" runat="server"
DataSourceID="SqlDataSource1" DataTextField="CategoryName"
DataValueField="CategoryID" AppendDataBoundItems="True">
<asp:ListItem Value="">- Select Category -</asp:ListItem>
</asp:DropDownList>
<span id="_span1">
<asp:DropDownList ID="ddlProduct" runat="server"
DataSourceID="SqlDataSource2" DataTextField="ProductName"
AppendDataBoundItems="True">
<asp:ListItem Value="">- Select Product -</asp:ListItem>
</asp:DropDownList>
</span><span id="_span2">
<asp:Button ID="btnBuy" runat="server" Text="Buy" Enabled="false" OnClick="btnBuy_Click" />
<br />
</span>
</div>
<asp:Label ID="Label1" runat="server"></asp:Label>
</div>
</form>
</body>
</html>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.IO;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Collections;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Globalization;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Reflection;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Web;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Web.UI;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
public partial class Callback : Page, ICallbackEventHandler
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private string _callbackEventArgument;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
protected void Page_Load(object sender, EventArgs e)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ddlCategory.Attributes.Add("onchange", "CallServer('FillProduct|'+this.value,_span1)");
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ddlProduct.Attributes.Add("onchange", "CallServer('ShowBuy|'+this.value,_span2)");
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
ICallbackEventHandler Members#region ICallbackEventHandler Members
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public string GetCallbackResult()
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string[] parts = _callbackEventArgument.Split('|');
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
object[] args = null;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string result = "";
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (parts.Length > 1)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
args = new object[parts.Length - 1];
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Array.Copy(parts, 1, args, 0, args.Length);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
MethodInfo method = this.GetType().GetMethod(parts[0]);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (method != null)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
result = (string)method.Invoke(this, args);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return result;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void RaiseCallbackEvent(string eventArgument)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_eventArgument = eventArgument;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.RaiseCallbackEvent(eventArgument);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string ICallbackEventHandler.GetCallbackResult()
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return this.GetCallbackResult();
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
#endregion
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public string FillProduct(string categoryID)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ddlCategory.SelectedValue = categoryID;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ddlProduct.DataBind();
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return RenderControl(ddlProduct);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public string ShowBuy(string ProductID)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
btnBuy.Enabled = !string.IsNullOrEmpty(ProductID);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return RenderControl(btnBuy);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
protected void btnBuy_Click(object sender, EventArgs e)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_div1.Visible = false;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Label1.Text = "Buy: " + Request.Form[ddlProduct.UniqueID];
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private string RenderControl(Control control)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
StringWriter writer1 = new StringWriter(CultureInfo.InvariantCulture);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
HtmlTextWriter writer2 = new HtmlTextWriter(writer1);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
control.RenderControl(writer2);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
writer2.Flush();
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
writer2.Close();
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return writer1.ToString();
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
在ASP.NET 2.0里面,我们可以轻松的来做到这点了。服务器端任何实现了System.Web.UI.ICallbackEventHandler接口的控件,都可以通过RaiseCallbackEvent()方法来处理从页面上的JS脚本传递过来的请求和数据,处理后,再将结果传回给页面。这项能力的底层仍然是XMLHTTP。 下面是一个简单的演示:
在页面上,我们放上两个文本框和一个按钮:
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<INPUT id="txtMessage">
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<INPUT onclick="callToServer();" type="button" value="Call to Server">
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
Result : <INPUT id="txtResult" >当点击按钮的时候,将调用JS脚本方法callToServer(),JS脚本如下:
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
function callToServer()
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
var param = document.getElementById("txtUsername").value;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
var context = "";
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<% = ClientScript %>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
function handleResultFromServer(result, context)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
document.getElementById("txtResult").value = result;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
}handleResultFromServer()方法则负责将从服务器传回的数据写到txtResult这个文本框里面。
再看看服务器端的代码:
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
public partial class Default_aspx : System.Web.UI.ICallbackEventHandler
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private String ClientScript
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
get
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return this.GetCallbackEventReference(this, "param", "handleResultFromServer", "context");
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public string RaiseCallbackEvent(string eventArgument)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return "客户端在[" + DateTime.Now.ToString() + "]传送来 [" + eventArgument + "].";
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
} 我们让页面直接实现ICallbackEventHandler接口,然后接口定义的RaiseCallbackEvent()方法中将服务器的时间和传来的数据一起返回回去。
ClientScript属性的作用是,它调用了页面的GetCallbackEventReference()方法,获得了让客户端有能力调用服务器端方法的JS脚本,并输出到页面的callToServer()方法中,这样,点击页面按钮时,就开始执行页面上包含了调用服务器方法的的callToServer()方法。
注意GetCallbackEventReference()方法的参数,在参数中,我们定义了客户端的哪个变量包含了要传递给服务器,服务器方法执行后,调用客户端的哪个方法等信息。实现步骤:首先,调用Page.GetCallbackEvenReference以获取对某个特定函数(可以从客户端脚本中调用该函数,以执行到服务器的XM—HTTP回调)的应用。asp.net提供了该函数的名称和实现。其次,在客户端脚本中编写一个将在回调时调用的方法。方法名称是传递给GetCallbackEventReference的参数之一。第三,在页面中实现ICallbackEventHandler接口,该接口包含一个方法—RaiseCallbackEvent,当回调发生时,该方法将在服务器段调用,RaiseCallbackEvent所返回的字符串讲被返回到第二步所述的方法
下面是一个例子:
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
<%
![](http://www.cnblogs.com/Images/dot.gif)
@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<html>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<body>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<h1>Please Register</h1>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<hr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<form runat="server">
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<table>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td>First Name</td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td><asp:TextBox ID="FirstName" RunAt="server" /></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td>Last Name</td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td><asp:TextBox ID="LastName" RunAt="server" /></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td>Address 1</td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td><asp:TextBox ID="Address1" RunAt="server" /></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td>Address 2</td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td><asp:TextBox ID="Address2" RunAt="server" /></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td>City</td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td><asp:TextBox ID="City" RunAt="server" /></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td>State</td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td><asp:TextBox ID="State" RunAt="server" /></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td>Zip Code</td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td><asp:TextBox ID="Zip" RunAt="server" /></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td><asp:Button ID="AutofillButton" Text="Autofill"
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
RunAt="server" /></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</table>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</form>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</body>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</html>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
<script language="javascript">
![](http://www.cnblogs.com/Images/dot.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Function called when callback returns
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
function __onCallbackCompleted (result, context)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Display the string returned by the server's RaiseCallbackEvent
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// method in the input field named "City"
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
document.getElementById ('City').value = result;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</script>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
<script language="C#" runat="server">
![](http://www.cnblogs.com/Images/dot.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void Page_Load (Object sender, EventArgs e)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Get callback event reference (e.g., "__doCallback (
![](http://www.cnblogs.com/Images/dot.gif)
)")
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string cbref = GetCallbackEventReference (this,
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
"document.getElementById ('Zip').value",
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
"__onCallbackCompleted", "null", "null");
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Wire the callback event reference to the Autofill button with
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// an onclick attribute (and add "return false" to event reference
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// to prevent a postback from occurring)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
AutofillButton.Attributes.Add ("onclick",
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
cbref + "; return false;");
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Server-side callback event handler
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string ICallbackEventHandler.RaiseCallbackEvent (string arg)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (arg.StartsWith ("378"))
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return "Oak Ridge";
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else if (arg.StartsWith ("379"))
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return "Knoxville";
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return "Unknown";
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</script>
可能你觉得callback很弱,AJAX才够强。其实网上大多数callback的示例代码都是不太正确的(包括MSDN)。这里提供了一种不同的使用callback的方法。只用很少的javascript就实现了一个联级下拉框。你会发现:轻量级的callback其实也很好用。
在这里我有两个DropDownList,ddlCategory和ddlProduct。要求ddlCategory变化后ddlProduct无刷新的填充新的项目。
要使用Callback首先要继承ICallbackEventHandler接口:
public partial class Callback : Page, ICallbackEventHandler 或:
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
正式版的ICallbackEventHandler要实现以下两个方法:
string GetCallbackResult ()
void RaiseCallbackEvent (string eventArgument)
eventArgument现在改为由RaiseCallbackEvent接收,而不是由GetCallbackResult直接接受了。目的是为了让你可以在RaiseCallbackEvent中做一些初始化操作,这点在编写支持callback的控件时特别有用,有兴趣的话你可以参考GridView和DetailView中RaiseCallbackEvent的代码。在这里我只使用最简单的方式,把eventArgument存到一个私有成员中:
private string _callbackEventArgument;
protected virtual void RaiseCallbackEvent(string eventArgument)
{
this._callbackEventArgument = eventArgument;
}
在客户端触发callback需要使用到GetCallbackEventReference,正式版中的GetCallbackEventReference位于Page.ClientScript下。ClientScript是2.0中Page的一个新增成员,专门用于处理客户端教本(javascript),它是一个实例化的ClientScriptManager。
<script type="text/javascript">
function CallServer(arg, context)
{
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context")%>;
}
function ReceiveServerData(result, context)
{
...
}
</script>
protected void Page_Load(object sender, EventArgs e)
{
ddlCategory.Attributes.Add("onchange", "CallServer(....)");
}
在这里我使用了一个javascript函数CallServer来包装callback的触发,当然你也可把它直接挂到onchange或其他客户端事件上。不过用一个函数来包装的话,可以很方便的在callback前后做一些其他操作,下面我就会用到。
不知道你有没有发觉,我们传给callback两个参数:arg和context,但是RaiseCallbackEvent只得到一个(arg),另一个参数context会给原封不动的传给ReceiveServerDate。这个context到底有什么用呢?甚至连MSDN里的代码也没有很正确的使用这个参数。可能你觉得callback很弱,只传入一个string(arg)传出一个string(result),还要编写大量的javascript代码才能实现想要的功能。其实,只要正确使用上面那个context参数就可以用很少的javascript实现很理想的功能。
首先,我们拆分一下arg,把我们要调用的服务端方法放进去:
ddlCategory.Attributes.Add("onchange", "CallServer('FillProduct|'+this.value, ...)");
然后用反射在服务器端调用这个方法(FillProduct):
public string GetCallbackResult()
{
string[] parts = _callbackEventArgument.Split('|');
return this.GetType().GetMethod(parts[0]).Invoke(this, new objcet[]{parts[1]}) ;
}
我们来看看FillProduct会返回些什么:
public string FillProduct(string categoryID)
{
ddlCategory.SelectedValue = categoryID;
ddlProduct.DataBind();
StringWriter writer1 = new StringWriter(CultureInfo.InvariantCulture);
HtmlTextWriter writer2 = new HtmlTextWriter(writer1);
ddlProduct.RenderControl(writer2);
writer2.Flush();
writer2.Close();
return writer1.ToString();
}
你可以看到,我把需要更新的ddlProduct整个重新Render后传回来了,也就是说要用新生成的ddlProduct的HTML替换原来的ddlProduct的HTML。怎么做到这一点呢?context参数要出马了:
<script type="text/javascript">
function CallServer(arg, context)
{
[b]context.innerHTML [/b]= "Loading
![](http://www.cnblogs.com/Images/dot.gif)
";
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context")%>;
}
function ReceiveServerData(result, context)
{
[b]context.innerHTML [/b]= result;
}
</script>
.....
<asp:DropDownList ID="ddlCategory" runat="server" DataSourceID="SqlDataSource1"
DataTextField="CategoryName" DataValueField="CategoryID" AppendDataBoundItems="True" >
<asp:ListItem Value="">- Select Category -</asp:ListItem>
</asp:DropDownList>
<span id="_span1">
<asp:DropDownList ID="ddlProduct" runat="server" DataSourceID="SqlDataSource2"
DataTextField="ProductName" AppendDataBoundItems="True">
<asp:ListItem Value="">- Select Product -</asp:ListItem>
</asp:DropDownList>
</span>
protected void Page_Load(object sender, EventArgs e)
{
ddlCategory.Attributes.Add("onchange", "CallServer('FillProduct|'+this.value, _span1)");
} 原来我把要更新的ddlProduct放在_span1里,context就是用来传递这个_span1的。只要用新生成的HTML填充这个_span1,ddlProduct的更新就OK了。这样我们就很轻松的完成了一个无刷新的联级下拉框。
需要注意的是,要在页面提交(postback)后取得这个ddlProduct的值,需要使用
Request.Form[ddlProduct.UniqueID]
因为viewstate并没有被更新。
在下面的完整代码里我还做了如下两件事,以提高代码的复用性: 对_callbackEventArgument稍加处理,以便调用任意多个参数的方法(FillProduct只有一个参数)
提取了FillProduct中Rander Control的那部分,以便于其他方法也可以使用。(这项操作用VS2005的Refactor很容易就完成了
其实你可以把这两部分整理到一个CallbackHelp类中,这样复用性就更高了。
Enjoy it.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Callback.aspx.cs" Inherits="Callback" %>
<!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">
<script type="text/javascript">
function CallServer(arg, context)
{
context.innerHTML = "Loading
![](http://www.cnblogs.com/Images/dot.gif)
";
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context") %>;
}
function ReceiveServerData(result, context)
{
context.innerHTML = result;
}
</script>
<head runat="server">
<title>Callback</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString1 %>"
SelectCommand="SELECT [CategoryID], [CategoryName] FROM [Categories]">
</asp:SqlDataSource>
<asp:SqlDataSource ID="SqlDataSource2" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString1 %>"
SelectCommand="SELECT [ProductID], [ProductName] FROM [Products] WHERE ([CategoryID] = @CategoryID)">
<SelectParameters>
<asp:ControlParameter ControlID="ddlCategory" Name="CategoryID"
PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>
<div id="_div1" runat="server">
<asp:DropDownList ID="ddlCategory" runat="server"
DataSourceID="SqlDataSource1" DataTextField="CategoryName"
DataValueField="CategoryID" AppendDataBoundItems="True">
<asp:ListItem Value="">- Select Category -</asp:ListItem>
</asp:DropDownList>
<span id="_span1">
<asp:DropDownList ID="ddlProduct" runat="server"
DataSourceID="SqlDataSource2" DataTextField="ProductName"
AppendDataBoundItems="True">
<asp:ListItem Value="">- Select Product -</asp:ListItem>
</asp:DropDownList>
</span><span id="_span2">
<asp:Button ID="btnBuy" runat="server" Text="Buy" Enabled="false" OnClick="btnBuy_Click" />
<br />
</span>
</div>
<asp:Label ID="Label1" runat="server"></asp:Label>
</div>
</form>
</body>
</html>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.IO;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Collections;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Globalization;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Reflection;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Web;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Web.UI;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
public partial class Callback : Page, ICallbackEventHandler
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private string _callbackEventArgument;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
protected void Page_Load(object sender, EventArgs e)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ddlCategory.Attributes.Add("onchange", "CallServer('FillProduct|'+this.value,_span1)");
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ddlProduct.Attributes.Add("onchange", "CallServer('ShowBuy|'+this.value,_span2)");
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
ICallbackEventHandler Members#region ICallbackEventHandler Members
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public string GetCallbackResult()
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string[] parts = _callbackEventArgument.Split('|');
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
object[] args = null;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string result = "";
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (parts.Length > 1)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
args = new object[parts.Length - 1];
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Array.Copy(parts, 1, args, 0, args.Length);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
MethodInfo method = this.GetType().GetMethod(parts[0]);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (method != null)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
result = (string)method.Invoke(this, args);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return result;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void RaiseCallbackEvent(string eventArgument)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_eventArgument = eventArgument;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.RaiseCallbackEvent(eventArgument);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string ICallbackEventHandler.GetCallbackResult()
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return this.GetCallbackResult();
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
#endregion
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public string FillProduct(string categoryID)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ddlCategory.SelectedValue = categoryID;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ddlProduct.DataBind();
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return RenderControl(ddlProduct);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public string ShowBuy(string ProductID)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
btnBuy.Enabled = !string.IsNullOrEmpty(ProductID);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return RenderControl(btnBuy);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
protected void btnBuy_Click(object sender, EventArgs e)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_div1.Visible = false;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Label1.Text = "Buy: " + Request.Form[ddlProduct.UniqueID];
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private string RenderControl(Control control)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
StringWriter writer1 = new StringWriter(CultureInfo.InvariantCulture);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
HtmlTextWriter writer2 = new HtmlTextWriter(writer1);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
control.RenderControl(writer2);
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
writer2.Flush();
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
writer2.Close();
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return writer1.ToString();
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
在ASP.NET 2.0里面,我们可以轻松的来做到这点了。服务器端任何实现了System.Web.UI.ICallbackEventHandler接口的控件,都可以通过RaiseCallbackEvent()方法来处理从页面上的JS脚本传递过来的请求和数据,处理后,再将结果传回给页面。这项能力的底层仍然是XMLHTTP。 下面是一个简单的演示:
在页面上,我们放上两个文本框和一个按钮:
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<INPUT id="txtMessage">
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<INPUT onclick="callToServer();" type="button" value="Call to Server">
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
Result : <INPUT id="txtResult" >当点击按钮的时候,将调用JS脚本方法callToServer(),JS脚本如下:
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
function callToServer()
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
var param = document.getElementById("txtUsername").value;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
var context = "";
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<% = ClientScript %>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
function handleResultFromServer(result, context)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
document.getElementById("txtResult").value = result;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
}handleResultFromServer()方法则负责将从服务器传回的数据写到txtResult这个文本框里面。
再看看服务器端的代码:
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
public partial class Default_aspx : System.Web.UI.ICallbackEventHandler
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private String ClientScript
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
get
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return this.GetCallbackEventReference(this, "param", "handleResultFromServer", "context");
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public string RaiseCallbackEvent(string eventArgument)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return "客户端在[" + DateTime.Now.ToString() + "]传送来 [" + eventArgument + "].";
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
} 我们让页面直接实现ICallbackEventHandler接口,然后接口定义的RaiseCallbackEvent()方法中将服务器的时间和传来的数据一起返回回去。
ClientScript属性的作用是,它调用了页面的GetCallbackEventReference()方法,获得了让客户端有能力调用服务器端方法的JS脚本,并输出到页面的callToServer()方法中,这样,点击页面按钮时,就开始执行页面上包含了调用服务器方法的的callToServer()方法。
注意GetCallbackEventReference()方法的参数,在参数中,我们定义了客户端的哪个变量包含了要传递给服务器,服务器方法执行后,调用客户端的哪个方法等信息。实现步骤:首先,调用Page.GetCallbackEvenReference以获取对某个特定函数(可以从客户端脚本中调用该函数,以执行到服务器的XM—HTTP回调)的应用。asp.net提供了该函数的名称和实现。其次,在客户端脚本中编写一个将在回调时调用的方法。方法名称是传递给GetCallbackEventReference的参数之一。第三,在页面中实现ICallbackEventHandler接口,该接口包含一个方法—RaiseCallbackEvent,当回调发生时,该方法将在服务器段调用,RaiseCallbackEvent所返回的字符串讲被返回到第二步所述的方法
下面是一个例子:
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
<%
![](http://www.cnblogs.com/Images/dot.gif)
@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<html>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<body>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<h1>Please Register</h1>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<hr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<form runat="server">
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<table>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td>First Name</td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td><asp:TextBox ID="FirstName" RunAt="server" /></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td>Last Name</td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td><asp:TextBox ID="LastName" RunAt="server" /></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td>Address 1</td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td><asp:TextBox ID="Address1" RunAt="server" /></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td>Address 2</td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td><asp:TextBox ID="Address2" RunAt="server" /></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td>City</td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td><asp:TextBox ID="City" RunAt="server" /></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td>State</td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td><asp:TextBox ID="State" RunAt="server" /></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td>Zip Code</td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td><asp:TextBox ID="Zip" RunAt="server" /></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
<td><asp:Button ID="AutofillButton" Text="Autofill"
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
RunAt="server" /></td>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</table>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</form>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</body>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</html>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
<script language="javascript">
![](http://www.cnblogs.com/Images/dot.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Function called when callback returns
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
function __onCallbackCompleted (result, context)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Display the string returned by the server's RaiseCallbackEvent
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// method in the input field named "City"
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
document.getElementById ('City').value = result;
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</script>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
<script language="C#" runat="server">
![](http://www.cnblogs.com/Images/dot.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void Page_Load (Object sender, EventArgs e)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Get callback event reference (e.g., "__doCallback (
![](http://www.cnblogs.com/Images/dot.gif)
)")
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string cbref = GetCallbackEventReference (this,
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
"document.getElementById ('Zip').value",
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
"__onCallbackCompleted", "null", "null");
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Wire the callback event reference to the Autofill button with
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// an onclick attribute (and add "return false" to event reference
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// to prevent a postback from occurring)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
AutofillButton.Attributes.Add ("onclick",
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
cbref + "; return false;");
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Server-side callback event handler
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string ICallbackEventHandler.RaiseCallbackEvent (string arg)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (arg.StartsWith ("378"))
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return "Oak Ridge";
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else if (arg.StartsWith ("379"))
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return "Knoxville";
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return "Unknown";
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
</script>
![](http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif)
相关文章推荐
- 2.0正式版中callback的一些变化+使用示例(ASP.NET 2.0)
- 2.0正式版中callback的一些变化+使用示例(ASP.NET 2.0)
- 2.0正式版中callback的一些变化+使用示例(ASP.NET 2.0)
- 2.0正式版中callback的一些变化+使用示例(ASP.NET 2.0)
- ASP.NET 2.0 正式版中callback的一些变化+使用示例 (转载)
- 2.0正式版中callback的一些变化+使用示例(ASP.NET 2.0)
- ASP.NET 2.0 正式版中callback的一些变化+使用示例
- ASP.NET2.0正式版中callback的一些变化+使用示例
- Asp.net 2.0 自定义控件开发专题[详细探讨页面状态(视图状态和控件状态)机制及其使用场景](示例代码下载)
- Asp.net 2.0 自定义控件开发专题[详细探讨页面状态(视图状态和控件状态)机制及其使用场景](示例代码下载)
- ASP.NET 2.0 Client Callback 的一些问题
- asp.net 2.0 自定义控件中的使用嵌入资源的一些总结
- Asp.net 2.0 自定义控件开发专题[详细探讨页面状态(视图状态和控件状态)机制及其使用场景](示例代码下载)
- AggregateCacheDependency、CacheDependency、SqlCacheDependency Asp.net 2.0和Sql Server的缓存管理和使用ObjectBuilder改造PetShop4 的缓存示例
- 使用ASP.NET 2.0 的一些问题!(11.22更新)
- Asp.net 2.0 自定义控件开发专题[详细探讨页面状态(视图状态和控件状态)机制及其使用场景](示例代码下载)
- Asp.net 2.0 自定义控件开发专题[详细探讨页面状态(视图状态和控件状态)机制及其使用场景](示例代码下载)
- Asp.net 2.0 自定义控件开发专题[详细探讨页面状态(视图状态和控件状态)机制及其使用场景](示例代码下载)
- Asp.net 2.0 自定义控件开发专题[详细探讨页面状态(视图状态和控件状态)机制及其使用场景](示例代码下载)
- ASP.NET 2.0使用FileUpload控件上传文件示例