如何:引发和使用事件

更新:2007 年 11 月

下面的示例程序阐释如何在一个类中引发一个事件,然后在另一个类中处理该事件。 AlarmClock 类定义公共事件 Alarm,并提供引发该事件的方法。 AlarmEventArgs 类派生自 EventArgs,并定义 Alarm 事件特定的数据。 WakeMeUp 类定义处理 Alarm 事件的 AlarmRang 方法。 AlarmDriver 类一起使用类,将使用 WakeMeUp 的 AlarmRang 方法设置为处理 AlarmClock 的 Alarm 事件。

该示例程序使用事件和委托引发事件中详细说明的概念。

示例

// EventSample.cs.
//
namespace EventSample
{  
   using System;
   using System.ComponentModel;
   
   // Class that contains the data for 
   // the alarm event. Derives from System.EventArgs.
   //
   public class AlarmEventArgs : EventArgs 
   {  
      private readonly bool snoozePressed ;
      private readonly int nrings;
      
      //Constructor.
      //
      public AlarmEventArgs(bool snoozePressed, int nrings) 
      {
         this.snoozePressed = snoozePressed;
         this.nrings = nrings;
      }
      
      // The NumRings property returns the number of rings
      // that the alarm clock has sounded when the alarm event 
      // is generated.
      //
      public int NumRings
      {     
         get { return nrings;}      
      }
      
      // The SnoozePressed property indicates whether the snooze
      // button is pressed on the alarm when the alarm event is generated.
      //
      public bool SnoozePressed 
      {
         get {return snoozePressed;}
      }
      
      // The AlarmText property that contains the wake-up message.
      //
      public string AlarmText 
      {
         get 
         {
            if (snoozePressed)
            {
               return ("Wake Up!!! Snooze time is over.");
            }
            else 
            {
               return ("Wake Up!");
            }
         }
      }  
   }
   
   // Delegate declaration.
   //
   public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);
   
   // The Alarm class that raises the alarm event.
   //
   public class AlarmClock 
   {  
      private bool snoozePressed = false;
      private int nrings = 0;
      private bool stop = false;
      
      // The Stop property indicates whether the 
      // alarm should be turned off.
      //
      public bool Stop 
      {
         get {return stop;}
         set {stop = value;}
      }
      
      // The SnoozePressed property indicates whether the snooze
      // button is pressed on the alarm when the alarm event is generated.
      //
      public bool SnoozePressed
      {
         get {return snoozePressed;}
         set {snoozePressed = value;}
      }
      // The event member that is of type AlarmEventHandler.
      //
      public event AlarmEventHandler Alarm;

      // 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)
      {
        AlarmEventHandler handler = Alarm; 
        if (handler != null) 
        { 
           // Invokes the delegates. 
           handler(this, e); 
        }
      }
      
      // This alarm clock does not have
      // a user interface. 
      // To simulate the alarm mechanism it has a loop
      // that raises the alarm event at every iteration
      // with a time delay of 300 milliseconds,
      // if snooze is not pressed. If snooze is pressed,
      // the time delay is 1000 milliseconds.
      //
      public void Start()
      {
         for (;;)    
         {
            nrings++;      
            if (stop)
            {
               break;
            }
            
            else if (snoozePressed)
            {
               System.Threading.Thread.Sleep(1000);
               {
                  AlarmEventArgs e = new AlarmEventArgs(snoozePressed, 
                     nrings);
                  OnAlarm(e);
               }
            }
            else
            {
               System.Threading.Thread.Sleep(300);
               AlarmEventArgs e = new AlarmEventArgs(snoozePressed, 
                  nrings);
               OnAlarm(e);
            }           
         }
      }
   }
   
   // The WakeMeUp class has a method AlarmRang that handles the
   // alarm event.
   //
   public class WakeMeUp
   {
      
      public void AlarmRang(object sender, AlarmEventArgs e)
      {
         
         Console.WriteLine(e.AlarmText +"\n");
         
         if (!(e.SnoozePressed))
         {
            if (e.NumRings % 10 == 0)
            {
               Console.WriteLine(" Let alarm ring? Enter Y");
               Console.WriteLine(" Press Snooze? Enter N"); 
               Console.WriteLine(" Stop Alarm? Enter Q");
               String input = Console.ReadLine();
               
               if (input.Equals("Y") ||input.Equals("y")) return;
               
               else if (input.Equals("N") || input.Equals("n"))
               {
                  ((AlarmClock)sender).SnoozePressed = true;
                  return;
               }
               else
               {
                  ((AlarmClock)sender).Stop = true;
                  return;
               }
            }
         }
         else
         {
            Console.WriteLine(" Let alarm ring? Enter Y"); 
            Console.WriteLine(" Stop Alarm? Enter Q");
            String input = Console.ReadLine();
            if (input.Equals("Y") || input.Equals("y")) return;
            else 
            {
               ((AlarmClock)sender).Stop = true;
               return;
            }
         }
      }
   }
   
   
   // The driver class that hooks up the event handling method of
   // WakeMeUp to the alarm event of an Alarm object using a delegate.
   // In a forms-based application, the driver class is the
   // form.
   //
   public class AlarmDriver
   {  
      public static void Main (string[] args)
      {  
         // Instantiates the event receiver.
         WakeMeUp w= new WakeMeUp();
                  
         // Instantiates the event source.
         AlarmClock clock = new AlarmClock();

         // Wires the AlarmRang method to the Alarm event.
         clock.Alarm += new AlarmEventHandler(w.AlarmRang);

         clock.Start();
      }
   }   
}
' EventSample.vb.
'
Option Explicit
Option Strict

Imports System
Imports System.ComponentModel
Imports Microsoft.VisualBasic

Namespace EventSample
   
   ' Class that contains the data for 
   ' the alarm event. Derives from System.EventArgs.
   '
   Public Class AlarmEventArgs
      Inherits EventArgs
      Private _snoozePressed As Boolean
      Private nrings As Integer
      
      'Constructor.
      '
      Public Sub New(snoozePressed As Boolean, nrings As Integer)
         Me._snoozePressed = snoozePressed
         Me.nrings = nrings
      End Sub
      
      ' The NumRings property returns the number of rings
      ' that the alarm clock has sounded when the alarm event 
      ' is generated.
      '
      Public ReadOnly Property NumRings() As Integer
         Get
            Return nrings
         End Get
      End Property 
      
      ' The SnoozePressed property indicates whether the snooze
      ' button is pressed on the alarm when the alarm event is generated.
      '
      Public ReadOnly Property SnoozePressed() As Boolean
         Get
            Return _snoozePressed
         End Get
      End Property 
      
      ' The AlarmText property that contains the wake-up message.
      '
      Public ReadOnly Property AlarmText() As String
         Get
            If _snoozePressed Then
               Return "Wake Up!!! Snooze time is over."
            Else
               Return "Wake Up!"
            End If
         End Get
      End Property
   End Class
   
   
   ' Delegate declaration.
   '
   Public Delegate Sub AlarmEventHandler(sender As Object, _
                                         e As AlarmEventArgs)

   ' The Alarm class that raises the alarm event.
   '
   Public Class AlarmClock
      Private _snoozePressed As Boolean = False
      Private nrings As Integer = 0
      Private stopFlag As Boolean = False
      
      ' The Stop property indicates whether the 
      ' alarm should be turned off.
      '
      Public Property [Stop]() As Boolean
         Get
            Return stopFlag
         End Get
         Set
            stopFlag = value
         End Set
      End Property 
      
      ' The SnoozePressed property indicates whether the snooze
      ' button is pressed on the alarm when the alarm event is generated.
      '
      Public Property SnoozePressed() As Boolean
         Get
            Return _snoozePressed
         End Get
         Set
            _snoozePressed = value
         End Set
      End Property

      ' The event member that is of type AlarmEventHandler.
      '
      Public Event Alarm As AlarmEventHandler
      
      ' 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)
         RaiseEvent Alarm(Me, e)
      End Sub
      
      
      ' This alarm clock does not have
      ' a user interface. 
      ' To simulate the alarm mechanism it has a loop
      ' that raises the alarm event at every iteration
      ' with a time delay of 300 milliseconds,
      ' if snooze is not pressed. If snooze is pressed,
      ' the time delay is 1000 milliseconds.
      '
      Public Sub Start()
         Do
            nrings += 1
            If stopFlag Then
               Exit Do
            
            Else
               If _snoozePressed Then
                  System.Threading.Thread.Sleep(1000)
                  If (True) Then
                     Dim e As New AlarmEventArgs(_snoozePressed, nrings)
                     OnAlarm(e)
                  End If
               Else
                  System.Threading.Thread.Sleep(300)
                  Dim e As New AlarmEventArgs(_snoozePressed, nrings)
                  OnAlarm(e)
               End If
            End If
         Loop
      End Sub
   End Class
  
   ' The WakeMeUp class has a method AlarmRang that handles the
   ' alarm event.
   '
   Public Class WakeMeUp
      Public Sub AlarmRang(sender As Object, e As AlarmEventArgs)
         
         Console.WriteLine((e.AlarmText + ControlChars.Cr))
         
         If Not e.SnoozePressed Then
            If e.NumRings Mod 10 = 0 Then
               Console.WriteLine(" Let alarm ring? Enter Y")
               Console.WriteLine(" Press Snooze? Enter N")
               Console.WriteLine(" Stop Alarm? Enter Q")
               Dim input As String = Console.ReadLine()
               
               If input.Equals("Y") Or input.Equals("y") Then
                  Return
               
               Else
                  If input.Equals("N") Or input.Equals("n") Then
                     CType(sender, AlarmClock).SnoozePressed = True
                     Return
                  Else
                     CType(sender, AlarmClock).Stop = True
                     Return
                  End If
               End If
            End If
         Else
            Console.WriteLine(" Let alarm ring? Enter Y")
            Console.WriteLine(" Stop Alarm? Enter Q")
            Dim input As String = Console.ReadLine()
            If input.Equals("Y") Or input.Equals("y") Then
               Return
            Else
               CType(sender, AlarmClock).Stop = True
               Return
            End If
         End If
      End Sub
   End Class
   
   ' The driver class that hooks up the event handling method of
   ' WakeMeUp to the alarm event of an Alarm object using a delegate.
   ' In a forms-based application, the driver class is the
   ' form.
   '
   Public Class AlarmDriver
      Public Shared Sub Main()
         ' Instantiates the event receiver.
         Dim w As New WakeMeUp()
         
         ' Instantiates the event source.
         Dim clock As New AlarmClock()
         
         ' Wires the AlarmRang method to the Alarm event.
         AddHandler clock.Alarm, AddressOf w.AlarmRang
         
         clock.Start()
      End Sub
   End Class
End Namespace

请参见

概念

引发事件

事件和委托

其他资源

处理和引发事件