对事件与委托的理解(2) 引发事件

事件功能是由三个互相联系的元素提供的:提供事件数据的类、事件委托和引发事件的类。.NET Framework 具有命名与事件相关的类和方法的约定。如果想要您的类引发一个名为 EventName 的事件,您需要以下元素。

  • 持有事件数据的类,名为 EventNameEventArgs。该类必须从 System.EventArgs 导出。
  • 事件的委托,名为 EventNameEventHandler。
  • 引发事件的类。该类必须提供:
    1. 事件声明。
      [C#]
      public event EventNameEventHandler EventName;

      [Visual Basic]
      Public Event EventName As EventNameEventHandler

    2. 引发事件的方法,名为 OnEventName

.NET Framework 类库或第三方类库中可能已经定义了事件数据类和事件委托类。在这种情况下,您就不需要定义这些类了。

提供事件功能
定义一个提供事件数据的类。该类必须从 System.EventArgs(它是事件数据的基类)导出。示例如下。
注意   如果已存在事件的事件数据类,或者没有与您的事件关联的数据,则不需要该步骤。如果没有事件数据,请使用基类 System.EventArgs。
[C#]
public class AlarmEventArgs : EventArgs {
   private readonly int nrings = 0;
   private readonly bool snoozePressed = false;
  
   //Properties.
   public string AlarmText { 
      ...
   }
   public int NumRings {
      ...
   }
   public bool SnoozePressed{
      ...
   }
   ...
}
[Visual Basic]
Public Class AlarmEventArgs
   Inherits EventArgs
   Private nrings As Integer = 0
   Private _snoozePressed As Boolean = False
  
   'Properties.
   Public ReadOnly Property AlarmText() As String
      ...
   End Property
  
   Public ReadOnly Property NumRings() As Integer
      ...
   End Property
  
   Public ReadOnly Property SnoozePressed() As Boolean
      ...
   End Property
   ...
End Class
声明事件的委托,如下面的示例所示。
注意   如果事件不生成数据,您不需要声明自定义委托。在这种情况下,请使用基事件处理程序 System.ComponentModel.EventHandler。
[C#]
public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);
[Visual Basic]
Public Delegate Sub AlarmEventHandler(sender As Object, e As AlarmEventArgs)
使用 event 关键字(其类型是事件委托)在您的类中定义一个公共事件成员,如下面的示例所示。
[C#]
public class AlarmClock
{
 ...
 public event AlarmEventHandler Alarm;  
}
[Visual Basic]
Public Class AlarmClock
   ...
   Public Event Alarm As AlarmEventHandler
End Class
在 AlarmClock 类中,Alarm 事件是 AlarmEventHandler 类型的委托。当编译器遇到 event 关键字时,它创建一个私有成员,例如
[C#]
private AlarmEventHandler al = null;
以及 add_Alarm 和 remove_Alarm 这两个公共方法。这些方法是事件挂钩,它们允许委托和事件委托 al 合并或从事件委托 al 移除。这些细节对程序员是隐藏的。
注意   在除 C# 和 Visual Basic .NET 以外的其他语言中,编译器可能不自动生成与事件成员对应的代码,您可能需要显式地定义事件挂钩和私有委托字段。
在引发事件的类中提供一个受保护的方法。该方法的名称必须是 OnEventName。OnEventName 方法通过调用委托来引发事件。本主题最后的代码示例显示了 OnEventName 的实现。
注意   受保护的 OnEventName 方法也允许派生类重写事件,而不必向其附加委托。派生类必须始终调用基类的 OnEventName 方法以确保注册的委托接收到事件。
[C#]
public class AlarmClock
   {
   ...
   public event AlarmHandler Alarm;
   protected virtual void OnAlarm(AlarmEvent e){...}
   }
[Visual Basic]
Public Class AlarmClock
   ...
   Public Event Alarm As AlarmEventHandler
   Protected Overridable Sub OnAlarm(e As AlarmEventArgs)
      ...
   End Sub
End Class
下面的代码片段将本节中讨论的所有元素放到了一起。有关实现和使用事件的完整示例,请参见事件示例。
[C#]
//Step 1. Class that defines data for the event
//
public class AlarmEventArgs : EventArgs
   {  
      private readonly bool snoozePressed = false;
      private readonly int nrings = 0;
      // Constructor.
      public AlarmEventArgs(bool snoozePressed, int nrings) {...}
      // Properties.
      public int NumRings{ get { return nrings;}}
      public bool SnoozePressed { get { return snoozePressed;}}   
      public string AlarmText { get {...}}

   }
  
//Step 2. Delegate declaration.
//
public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);

// Class definition.
//
public class AlarmClock
{
//Step 3. The Alarm event is defined using the event keyword.
//The type of Alarm is AlarmEventHandler.
  public event AlarmEventHandler Alarm;
//
//Step 4. The protected OnAlarm method raises the event by invoking
//the delegates. The sender is always this, the current instance of
//the class.
//  
protected virtual void OnAlarm(AlarmEventArgs e)
   {
    if (Alarm != null)
     {
       //Invokes the delegates.
       Alarm(this, e);
      }
   }
}
[Visual Basic]
'Step 1. Class that defines data for the event
'
Public Class AlarmEventArgs
   Inherits EventArgs
   Private _snoozePressed As Boolean = False
   Private nrings As Integer = 0
  
   ' Constructor.
   Public Sub New(snoozePressed As Boolean, nrings As Integer)
      ...
   End Sub

   ' Properties.
   Public ReadOnly Property NumRings() As Integer
      Get
         Return nrings
      End Get
   End Property
  
   Public ReadOnly Property SnoozePressed() As Boolean
      Get
         Return _snoozePressed
      End Get
   End Property
  
   Public ReadOnly Property AlarmText() As String
      Get
         ...
      End Get
   End Property
End Class

'Step 2. Delegate declaration.
'
Public Delegate Sub AlarmEventHandler(sender As Object, e As AlarmEventArgs)

' Class definition.
'
Public Class AlarmClock
   'Step 3. The Alarm event is defined using the event keyword.
   'The type of Alarm is AlarmEventHandler.
   Public Event Alarm As AlarmEventHandler
  
   '
   'Step 4. The protected OnAlarm method raises the event by invoking
   'the delegates. The sender is always this, the current instance of
   'the class.
   '  
   Protected Overridable Sub OnAlarm(e As AlarmEventArgs)
      'Invokes the delegates.
      RaiseEvent Alarm(Me, e)
   End Sub
End Class

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值