当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > ASP.NET2.0服务器控件之捕获回传事件

ASP.NET
FreeTextBox(版本3.1.6)在ASP.Net 2.0中使用方法
.NET 常用功能和代码小结
在 .NET Framework 2.0 中未处理的异常导致基于 ASP.NET 的应用程序意外退出
asp.net IList查询数据后格式化数据再绑定控件
asp.net sql存储过程
asp.net 简单实现禁用或启用页面中的某一类型的控件
asp.net(c#)获取内容第一张图片地址的函数
The remote procedure call failed and did not execute的解决办法
ASP.NET 在线文件管理
asp.net 读取并修改config文件实现代码
ASP.NET Cookie 操作实现
asp.net Silverlight中的模式窗体
Silverlight中动态获取Web Service地址
asp.net Silverlight应用程序中获取载体aspx页面参数
asp.net 水晶报表隔行换色实现方法
asp.net 获取Gridview隐藏列的值
手动把asp.net的类生成dll文件的方法
asp.net 使用ObjectDataSource控件在ASP.NET中实现Ajax真分页
动态指定任意类型的ObjectDataSource对象的查询参数
asp.net Md5的用法小结

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 75 ::
收藏到网摘: n/a

1、实现捕获回传事件

如果服务器控件需要捕获来自客户端的回传事件,并想为该回传事件自定义服务器端事件处理逻辑,那么控件必须实现
System.Web.UI.IPostBackEventHandler接口。下面列举了该接口定义。

如上代码所示,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;

·实现事件属性结构,维护事件处理程序委托列表;

·在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>

 
另外,还有一个与捕获回传事件密切相关的属性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技术,为自定义服务器控件实现捕获回传事件的实现方法。通过这些内容,相信读者可以基本掌握实现控件捕获回传事件的方法。在随后的文章中,笔者将继续介绍实现事件处理的另一核心内容--处理回传数据。