事件冒泡

事件冒泡    [ 日期:2005-08-15 ]   [ 来自:微软 ][收藏此页]ASP.NET 页框架提供一种称为“事件冒泡”的技术,允许 子控件将事件沿其包容层次结构向上传播。事件冒泡允许在控件层次结构中更方便的位置引发事件,并且允许将事件处理程序附加到原始控件以及公开冒泡的事件的 控件上。

数据绑定控件(Repeater、DataList 和 DataGrid)使用事件冒泡将子控件(在项目模板内)引发的命令事 件公开为顶级事件。虽然 .NET Framework 中的 ASP.NET 服务器控件将事件冒泡用于命令事件(事件数据类是 从 CommandEventArgs 派生的事件),但是,服务器控件上定义的任何事件都可以冒泡。

控件可以通过从基类 System.Web.UI.Control 继承的两个方法参与事件冒泡。这两个方法是:OnBubbleEvent 和 RaiseBubbleEvent。以下代码片段显示了这些方法的签名。

[C#]
protected virtual bool OnBubbleEvent(
   object source,
   EventArgs args
);
protected void RaiseBubbleEvent(
   object source,
   EventArgs args 
);
[Visual Basic]
Overridable Protected Function OnBubbleEvent( _
   ByVal source As Object, _
   ByVal args As EventArgs _
) As Boolean
Protected Sub RaiseBubbleEvent( _
   ByVal source As Object, _
   ByVal args As EventArgs _
)
RaiseBubbleEvent 的实现是由 Control 提供的,并且不能被重写。RaiseBubbleEvent 沿层次结构向上将事件数据发送到控件的父级。若要处理或引发冒泡的事件,控件必须重写 OnBubbleEvent 方法。

使事件冒泡的控件执行以下三种操作之一。 

控件不执行任何操作,此时事件自动向上冒泡到其父级。 
控件进行一些处理并继续使事件冒泡。若要实现这一点,控件必须重写 OnBubbleEvent,并从 OnBubbleEvent 调用 RaiseBubbleEvent。以下代码片段(摘自模板化数据绑定控件示例)在检查事件参数的类型后使事件冒泡。 
[C#]
protected override bool OnBubbleEvent(object source, EventArgs e) {
            if (e is CommandEventArgs) {
                // Adds information about an Item to the  
                // CommandEvent.
                TemplatedListCommandEventArgs args =
                    new TemplatedListCommandEventArgs(this, source, (CommandEventArgs)e);
                RaiseBubbleEvent(this, args);
                return true;
            }
            return false;
        }
[Visual Basic]
Protected Overrides Function OnBubbleEvent(source As Object, e As EventArgs) As Boolean
   If TypeOf e Is CommandEventArgs Then
      ' Adds information about an Item to the  
      ' CommandEvent.
      Dim args As New TemplatedListCommandEventArgs(Me, source, CType(e, CommandEventArgs))
      RaiseBubbleEvent(Me, args)
      Return True
   End If
   Return False
End Function
控 件停止事件冒泡并引发和/或处理该事件。引发事件需要调用将事件调度给侦听器的方法。若要引发冒泡的事件,控件必须重写 OnBubbleEvent 以 调用引发此冒泡的事件的 OnEventName 方法。引发冒泡的事件的控件通常将冒泡的事件公开为顶级事件。以下代码片段(摘自模板化数据绑定控件示 例)引发一个冒泡的事件。 
[C#]
protected override bool OnBubbleEvent(object source, EventArgs e) {
    bool handled = false;

    if (e is TemplatedListCommandEventArgs) {
        TemplatedListCommandEventArgs ce = (TemplatedListCommandEventArgs)e;

        OnItemCommand(ce);
        handled = true;
    }
    return handled;
}
[Visual Basic]
Protected Overrides Function OnBubbleEvent(source As Object, e As EventArgs) As Boolean
   Dim handled As Boolean = False
   
   If TypeOf e Is TemplatedListCommandEventArgs Then
      Dim ce As TemplatedListCommandEventArgs = CType(e, TemplatedListCommandEventArgs)
      
      OnItemCommand(ce)
      handled = True
   End If
   Return handled
End Function
有关说明事件冒泡的示例,请参见事件冒泡控件示例和模板化数据绑定控件示例。

注 意   虽然启用事件冒泡的方法 OnBubbleEvent 符合用于引发事件的方法的标准 .NET Framework 命名模式,但是没有名 为 BubbleEvent 的事件。在停止事件冒泡的控件中,将冒泡事件公开为顶级事件。例如,DataList 控件将其模板中控件 的 Command 事件公开为 ItemCommand 事件。另请注意,在 .NET Framework 中 OnEventName 方法的标准 签名有一个参数 (protected void OnEventName (EventArgs e))。但是,OnBubbleEvent 有两个参 数,这是因为该事件起源于控件之外;第二个参数提供源。
到目前为止,本讨论说明了控件如何响应冒泡的事件。下面一节显示如何创作一个定义冒泡的事件的控件。

定义冒泡的事件
如果希望控件为它所定义的事件启用事件冒泡,则控件必须从引发该事件的 OnEventName 方法调用 RaiseBubbleEvent。不需要在该控件中做额外的工作。以下代码片段显示了一个控件,该控件定义了一个启用冒泡的 Command 事件。

[C#]
protected virtual void OnCommand(CommandEventArgs e) {
            CommandEventHandler handler = (CommandEventHandler)Events[EventCommand];
            if (handler != null)
                handler(this,e);

            // The Command event is bubbled up the control hierarchy.
            RaiseBubbleEvent(this, e);
        } 
[Visual Basic]
Protected Overridable Sub OnCommand(e As CommandEventArgs)
   Dim handler As CommandEventHandler = CType(Events(EventCommand), CommandEventHandler)
   If Not (handler Is Nothing) Then
      handler(Me, e)
   End If 
   ' The Command event is bubbled up the control hierarchy.
   RaiseBubbleEvent(Me, e)
End Sub
注意   事件冒泡并不限于命令事件。可以使用此处描述的机制使任何事件冒泡。
posted @ 2008-08-25 15:03  zzh  阅读(1795)  评论(0编辑  收藏  举报