ASP.NET2.0服务器控件之捕获回传事件

1. 实现捕获回传事件
  
  
  如果服务器控件需要捕获来自客户端的回传事件,并想为该回传事件自定义服务器端事件处理逻辑,那么控件必须实现 System.Web.UI.IPostBackEventHandler 接口。下面列举了该接口定义。
  
  public interface IPostBackEventHandler
  {
  
  void RaisePostBackEvent(string eventArgument);
  }
  
  
  如上代码所示, IPostBackEventHandler 接口仅包括一个成员方法 RaisePostBackEvent 。该方法使服务器控件能够处理将窗体发送到服务器时引发的事件,其参数 eventArgument 表示要传递到事件处理程序的可选事件参数。开发人员可以在 RaisePostBackEvent 方法中实现服务器控件回传过程中执行的逻辑。一般情况下, RaisePostBackEvent 方法将引发一个或者多个服务器端事件。以下代码片段显示了在服务器上引发 Click 事件的 RaisePostBackEvent 实现。
  
  public void RaisePostBackEvent(String eventArgument)
  {
  
  OnClick(EventArgs.Empty);
  }
  
  
  实现捕获回传事件并不是仅仅使服务器控件类实现 IPostBackEventHandler 接口,并实现该接口成员方法就可以的。开发人员还需要注意实现其他内容。下面列举了实现捕获回传事件过程中的三个要点。
  
  
  第一,也是最重要的,即自定义服务器控件类必须实现 IPostBackEventHandler 接口,并实现该接口成员 RaisePostBackEvent 方法。这一过程在上文中已经进行了介绍。
  
  
  第二,为控件分配 UniqueID
  
  
  定义引起回传事件的控件的 name 属性值为 UniqueID ,是正确实现 RaisePostBackEvent 方法的关键之一。当引发回传后,页框架就会搜索发送的内容,并确定发送对象的名称是否与实现 IPostBackEventHandler 的服务器控件的 UniqueID 对应。如果对应,页框架就会在该控件上调用 RaisePostBackEvent 方法。这里的重点是需要开发人员在呈现逻辑中,为控件的 name 属性分配 UniqueID 。下面列举了一个简单的代码示例。
  
  protected override void Render(HtmlTextWriter output)
  {
  
  output.Write("<INPUT TYPE=submit name="+this.UniqueID+"Value='Click Me' />");
  }
  
  
  如上代码所示,在控件呈现方法 Render 中,呈现了一个按钮,其 name 属性值为 UniqueID 。只有为引起回传的控件的 name 属性分配了 UniqueID ,才能够正确实现捕获回传事件。
  
  
  第三,实现事件属性结构。
  
  
  事件属性结构是一种优化的事件实现方式。在介绍之前,我们首先看看常见的控件事件实现方式。具体代码如下所示。
  
  ......
  public class WebCustomControl:WebControl,IPostBackEventHandler{
  
  // 声明 Click 事件委托
  
  public event EventHandler Click;
  
  // 实现 RaisePostBackEvent 方法
  
  void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) {
  
   OnClick(EventArgs.Empty);
  
  }
  
  // 定义 OnClick 事件处理程序
  
  protected virtual void OnClick(EventArgs e) {
  
   if(Click != null) { Click(this,e); }
  
  }
  
  ......
  }
  
  
  在以上代码中,包括了与事件定义相关的三个关键内容:一、定义 Click 事件委托;二、控件类实现了 IPostBackEventHandler 接口,其中当实现接口成员方法 RaisePostBackEvent 过程中,定义了事件处理程序 OnClick ;三、实现 OnClick 事件处理程序。以上实现方法简单易用,然而却存在一个缺点,即执行效率低。尤其是在一个类中引发多个事件的情况下,将会增加开销,浪费大量服务器资源,最终导致运行效率降低。
  
  
  为了解决以上问题,下面介绍一种优化的事件实现方式 -- 事件属性结构。该结构使用 System.ComponentModel.EventHandlerList 类,这个类提供一个简单的委托列表。通过使用该类所提供的相关方法,开发人员能够灵活的操作控件的事件处理程序委托列表。例如,控件中的 Click 事件,使用事件属性结构如下:
  
  protected static readonly object EventClick = new object();
  public event EventHandler Click{
  
  add {
  
   Events.AddHandler(EventClick,value);
  
  }
  
  remove {
  
   Events.RemoveHandler(EventClick,value);
  
  }
  }
  
  
  在事件属性结构定义之前,首先需要定义 Click 事件委托对象。由于每个事件仅创建一次,因此,需要声明为静态和只读的。然后,在属性结构中通过 AddHandler RemoveHandler 方法操作事件处理程序委托列表。当页面调用 Click 事件时,它向控件的 EventHandlerList 集合中添加或者删除处理程序。由于这种实现方法,在多个事件的声明过程中比普通的实现方法效率高,因此是非常值得推荐的方法。
  
  
  另外,在 OnClick 方法的实现过程中,当用一个事件属性时,必须从 EventHandlerList 中取回委托,并将其转换成 EventHandler 的类型。
  
  protected virtual void OnClick(EventArgs e){
  
  EventHandler clickHandler = (EventHandler)Events[EventClick];
  
  if(clickHandler != null) {
  
   clickHandler(this,e);
  
  }
  }
  
  
  请读者注意:事件属性结构不适用于 VB.net 语言,只能在 C# 等语言中应用。
  2.
典型应用
  
  
  实事求是的讲,以上捕获回传事件的理论介绍对于从未实现过服务器控件事件的读者而言,有些难以理解。为此,本小节通过一个典型的示例来具体说明捕获回传事件的实现方法。
  
  
  本例实现了一个自定义服务器控件 WebCustomControl 。该控件虽然呈现为一个按钮外观,但是其并不是从 Button 类继承而来。当单击该按钮时,控件将引起回传,服务器端自动捕获回传的单击事件,并且引发 Click 事件,执行对应事件处理程序。下面是服务器控件实现的源代码代码:
  
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Text;
  using System.Web;
  using System.Web.UI;
  using System.Web.UI.WebControls;
  namespace WebControlLibrary{ [DefaultEvent("Click")]
  [ToolboxData("<{0}:WebCustomControl runat=server></{0}:WebCustomControl>")]
  public class WebCustomControl : WebControl, IPostBackEventHandler {
  
  // 定义一个 Click 事件委托对象
  
  private static readonly object EventClick = new object();
  
  // 实现 Click 事件属性
  
  [Description("Click 事件属性 "), Category("Action") ]
  
  public event EventHandler Click {
  
   add {
  
    Events.AddHandler(EventClick, value);
  
   }
  
   remove {
  
    Events.RemoveHandler(EventClick, value);
  
   }
  
  }
  
 
  
  // 重写控件呈现方法 RenderContents
  
  
  protected override void RenderContents(HtmlTextWriter output) {
  
   output.Write("<input type='submit' name=" + this.UniqueID + " value= 请单击 />");
  
  }
  
  // 实现事件方法
  
  protected virtual void OnClick(EventArgs e) {
  
   EventHandler clickHandler = (EventHandler)Events[EventClick];
  
   if (clickHandler != null) {
  
    clickHandler(this, e);
  
   }
  
  }
  
  // 实现 IPostBackEventHandler 接口成员
  
  void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) {
  
   OnClick(EventArgs.Empty);
  
  }
  }
  }
  
  
  在 WebCustomControl 类中,实现了以下有关捕获回传事件处理的关键内容:
  
  
  ·控件类 WebCustomControl 实现 IPostBackEventHandler
  
  
  ·将引发回传的控件的 name 属性值设置 UniqueID
  
  
  な迪质录粜越峁梗な录沓绦蛭辛斜恚 ?BR>
  
  ·在 RaisePostBackEvent 方法中调用 OnClick 方法;
  
  
  下面的代码是应用自定义按钮 WebCustomControl Default.ASPx 源代码,显示效果如图 1 和图 2 所示。
  
  <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
  <%@ ReGISter TagPrefix="cc" Namespace="WebControlLibrary" Assembly="WebControlLibrary" %>
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <script runat="server">
  
  void wcc1_Click(object sender, EventArgs e) {
  
   message.Text = " 您刚才点击了上面的按钮 ";
  
  }
  </script>
  <html XMLns="http://www.w3.org/1999/xhtml">
  <head runat="server">
  <title>
捕获回传事件 </title>
  </head>
  <body>
  
  <form id="form1" runat="server">
  
  <center>
  
   <cc:WebCustomControl ID="wcc1" runat="server" OnClick="wcc1_Click" /> <br /> <br />
  
   <asp:Label ID="message" runat="server"></asp:Label>
  
  </center>
  </form>
  </body>
  </html>
  
  
  下图 1 和图 2 是应用效果图。  
   
            
   
  
 
     1 页面初始化效果图                                                      2 点击按钮后的效果图
  
  
  另外,还有一个与捕获回传事件密切相关的属性 AutoPostBack 。该属性用于控件的自动回传设置,很多标准的服务器控件中均包含该属性。对于开发人员来讲,是否需要在自行创建的服务器控件中定义该属性是很重要的,需要根据控件的功能需求认真考虑取舍。该属性的关键代码实现如下:
  
  //
定义属性 AutoPostBack
  public bool AutoPostBack{
  
  set {
  
   this._autoPostBack = value;
  
  }
  
  get {
  
   return this._autoPostBack;
  
  }
  }
  //
Render 方法中添加 Page.GetPostBackEventReference() 方法
  protected override void Render(HtmlTextWriter output){
  
  ......
  
  if(this.AutoPostBack) {
  
   writer.WriteAttribute("ontextchanged","JavaScript:" + Page.GetPostBackEventReference(this));
  
  }
  
  ......
  }
  
  
  由以上代码可知, AutoPostBack 属性的实现重点是 Page.GetPostBackEventReference 方法的应用。该方法获取对客户端脚本函数的引用,调用该函数将使服务器发送回该页,并返回一段表示客户端事件的字符串,实际是一些客户端代码。当 AutoPostBack="true" 时,服务器控件将发生自动回传,而不需通过 Click 事件等引发;当 AutoPostBack="false" ,则回传必须经过类似 Click 的事件引发。
  
  
  以上介绍的是有关捕获回传事件的具体实现方法。总体来讲不是非常复杂,然而,实现捕获回传事件的具体应用非常灵活,远远没有这么简单,这就需要读者不断的实践才能深入理解。
  
  
   3. 小结
  
  
  本文首先介绍了利用 ASP.NET 2.0 技术,为自定义服务器控件实现捕获回传事件的实现方法。通过这些内容,相信读者可以基本掌握实现控件捕获回传事件的方法。在随后的文章中,笔者将继续介绍实现事件处理的另一核心内容 -- 处理回传数据。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值