Web 应用程序的 ClientCallback 自定义控件






4.91/5 (46投票s)
一个客户端回调自定义控件以及如何在 WebForms 中使用它。
引言
在某些情况下,我们可能需要在页面的某一部分显示一个项目列表(该列表可以是排序的或分层的),并且在选择此列表中的一个项目时,在页面的另一半显示与其相关的所有详细信息。 所有这些都不需要回发或闪烁,这将给用户带来流畅而良好的感觉。
例如,我们有一个与财务相关的 Web 应用程序。 我们需要查看与我们的投资组合中的股票代码相关的详细信息(同一页面上列出了多个股票代码)。 选择股票代码后,所有详细信息以及该股票代码的当前状态都将显示在同一页面上,而无需任何回发或闪烁。
在这里,上述场景是使用 ASP.NET 2.0 中引入的客户端回调功能实现的。 我发现与此功能相关的相当多的代码可以嵌入到自定义控件中,这样可以方便使用。 此外,如果我们在一个页面上多次使用回调,它将减少大量的代码。 因此,我尝试开发一个“用户友好”的自定义控件来使用客户端回调功能。
背景
在我的当前项目中,我们遇到了一个需要对不同的制造零件进行分类的情况(由于分类中的分层结构,我们决定使用树视图控件)。 选择任何一个零件(节点)后,我们应该在同一页面上的网格中显示其状态和相关数据。 性能是客户的主要需求之一。 因此,根据需求,我们决定使用客户端回调功能。 该示例基于我的这种经验。
使用代码
首先,自定义控件的重要代码部分
除了从 WebControl
继承控件之外,我们还从 ICallbackEventHandler
继承它。
public class MyCustomCallBackControl : WebControl, ICallbackEventHandler {}
控件的 OnInit()
方法被重写。 与控件相关的回调脚本嵌入在此处。
// OnInit was overriden in order to attach a callback handler to the control
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
string callback = Page.ClientScript.GetCallbackEventReference(this, "input",
string.Concat(ID, "OnSuccess"), "context");
Page.ClientScript.RegisterClientScriptBlock(typeof(MyCustomCallBackControl),
ID, string.Concat("function ", ID,
"Callback(input, context) { ", callback, "; }"), true);
//Above line - Script added during runtime:
//function MyCustomCallBackControl1Callback(input, context)
//{
// WebForm_DoCallback('MyCustomCallBackControl1',
// input,MyCustomCallBackControl1OnSuccess,context,null,false);
//}
//General meaning of it:
// WebForm_DoCallback(eventTarget, eventArgument, eventCallback,
// context, errorCallback, useAsync)
}
我们需要编写与实现 ICallbackEventHandler
接口相关的 GetCallBackResult
和 RaiseCallBackEvent
方法。
// Event handler for code logic at server side on client-callback
// Event bubbling done here
public event EventHandler MyCallBackEvent;
public void RaiseCallbackEvent(string eventArgument)
{
argumentParameter = eventArgument;
if (MyCallBackEvent != null)
{
MyCallBackEvent(this, EventArgs.Empty);
}
}
public string GetCallbackResult()
{
//Returns back the output set during the callback
return renderedOutput;
}
客户端回调自定义控件现在可以使用了。
我们现在将研究如何在我们的网页上使用该控件。 我们将控件拖放到页面上,并为其定义代码隐藏处理程序,基本上就是调用回调控件时将运行的服务器代码。
// Bubbled event for Callback control placed
// One can handle the operations required during the callback out here.
protected void CallBackControl_Perform(object sender, EventArgs e)
{
DataTable dt = RetrieveDataTable(((
MyCustomControls.MyCustomCallBackControl)sender).ArgumentParameter);
gvTest.DataSource = dt;
gvTest.DataBind();
//Setting of the response output for callback
using (System.IO.StringWriter sw = new System.IO.StringWriter())
{
gvTest.RenderControl(new HtmlTextWriter(sw));
((MyCustomControls.MyCustomCallBackControl)sender).RenderedOutput = sw.ToString();
}
}
在我们的示例中,我们将树节点绑定到此回调控件。 这是使用 JavaScript 完成的。
//Client Side callback event attached
tNode.NavigateUrl = "javascript:OnNodeClick('" + tNode.Value + "');";
我们只剩下定义附加到自定义回调控件的 JavaScript 函数。 这些函数将在上面定义的 OnNodeClick
方法中绑定。
//Node Callback Click Event
function OnNodeClick(nodeID)
{
// Method name to call has a fixed naming convention
// CustomCallbackControl name + "Callback"
// Parameters to the function would be:
// 1st : Input
// 2nd : Context
MyCustomCallBackControl1Callback(nodeID, null);
}
// Function name has a fixed naming convention
// CustomCallbackControl name + "OnSuccess"
function MyCustomCallBackControl1OnSuccess(responseText)
{
// Based on responseText, action taken on client side
document.getElementById("tdGridView").style.display = "block";
document.getElementById("gvTest").outerHTML = responseText;
}
我们现在完成了控件的使用。 定义了 JavaScript 函数的命名约定,并且需要相应地给出。
关注点
性能非常好,而且具有简单而时尚的用户界面。 这是一个很好的经验,学习了使用 UpdatePanel
和回调控件之间的比较和差异。
将其设为自定义控件帮助很大。 即使是初学者也可以使用它,而无需过多了解其中发生的事情(它可以在同一页面上多次使用)。 该控件易于使用,并且成为了我 Web 股票中的一件不错的武器! :)
历史
- 2008 年 12 月 19 日:初始发布。