65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.91/5 (46投票s)

2008年12月19日

CPOL

3分钟阅读

viewsIcon

104991

downloadIcon

1018

一个客户端回调自定义控件以及如何在 WebForms 中使用它。

TestPageImage2.JPG

引言

在某些情况下,我们可能需要在页面的某一部分显示一个项目列表(该列表可以是排序的或分层的),并且在选择此列表中的一个项目时,在页面的另一半显示与其相关的所有详细信息。 所有这些都不需要回发或闪烁,这将给用户带来流畅而良好的感觉。

例如,我们有一个与财务相关的 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 接口相关的 GetCallBackResultRaiseCallBackEvent 方法。

// 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 日:初始发布。
© . All rights reserved.