方法 : クラスにイベントを実装する

以下の手順では、クラスにイベントを実装する方法について説明します。 最初の手順では、関連付けられたデータを持たないイベントを実装します。このイベントは、イベント データとして System.EventArgs クラスを使用し、デリゲート ハンドラーとして System.EventHandler クラスを使用します。 2 番目の手順では、カスタム データを持つイベントを実装します。このイベントは、イベント データおよびイベント ハンドラーのカスタム クラスを定義します。

注意

ここでは、クラスでイベントを宣言する方法と発生させる方法について説明します。そのイベントを処理するイベント ハンドラーの定義方法については説明しません。イベントを処理する方法については、「イベントの利用」および「方法 : イベントを発生させる/処理する」を参照してください。

イベントの発生と処理を説明する詳細なサンプルについては、「方法 : イベントを発生させる/処理する」を参照してください。

イベント固有のデータを持たないイベントを実装するには

  1. クラスにパブリック イベント メンバーを定義します。 イベント メンバーの型に System.EventHandler デリゲートを設定します。

    Public Class Countdown
        ' ...
    
        Public Event CountdownCompleted As EventHandler
    End Class
    
    public class Countdown 
    {
        // ...
    
        public event EventHandler CountdownCompleted;   
    }
    
  2. イベントを発生させるクラスにプロテクト メソッドを提供します。 メソッドに On EventName という名前を付けます。 このメソッド内で対象のイベントを発生させます。 C# コードでは、イベントを発生させる前にイベントが null かどうかを確認する必要があることに注意してください。 これによって、イベント ハンドラーが関連付けられていない場合にイベントの発生時にスローされる NullReferenceException を処理する必要がなくなります。 この例では、CountDown クラスはイベントを発生させるだけで、それに対するハンドラーは提供しないため、この確認を行う必要があります。

    Public Class Countdown
       ' ...
    
       Public Event CountdownCompleted As EventHandler
    
       Protected Overridable Sub OnCountdownCompleted(e As EventArgs)
          RaiseEvent CountdownCompleted(Me, e)
       End Sub
    End Class
    
    public class Countdown 
    {
        public event EventHandler CountdownCompleted;   
    
        protected virtual void OnCountdownCompleted(EventArgs e)
        {
            if (CountdownCompleted != null)
                CountdownCompleted(this, e);
        }
    }
    
  3. クラスでいつイベントを発生させるかを決定します。 OnEventName を呼び出して、イベントを発生させます。

    Public Class Countdown
       Dim internalCounter As Integer = 0
        ' ...
    
       Public Event CountdownCompleted As EventHandler
    
       Protected Overridable Sub OnCountdownCompleted(e As EventArgs)
          RaiseEvent CountdownCompleted(Me, e)
       End Sub
    
       Public Sub Decrement()
          internalCounter -= 1
          If internalCounter = 0
             OnCountdownCompleted(New EventArgs())
          End If
       End Sub
    End Class
    
    public class Countdown 
    {
       int internalCounter = 0;
       // ...
    
       public event EventHandler CountdownCompleted;   
    
        protected virtual void OnCountdownCompleted(EventArgs e)
        {
            if (CountdownCompleted != null)
                CountdownCompleted(this, e);
        }
    
       public void Decrement()
       {
          internalCounter--;
          if (internalCounter == 0)
             OnCountdownCompleted(new EventArgs());
       }
    }
    

イベント固有のデータを持つイベントを実装するには

  1. イベントのデータを提供するクラスを定義します。 クラスに EventNameArgs という名前を付け、System.EventArgs からこのクラスを派生させ、イベント固有のメンバーを追加します。

    Public Class AlarmEventArgs : Inherits EventArgs
       Private nRings As Integer = 0
       Private pressed As Boolean = False
       Private text As String = "The alarm is ringing!"
    
       ' Constructor.
       Public Sub New(ByVal snoozePressed As Boolean, ByVal nRings As Integer) 
          Me.pressed = snoozePressed
          Me.nRings = nRings
       End Sub
    
       ' Properties.
       Public Property AlarmText() As String
          Get
             Return Me.text
          End Get
          Set
             Me.text = value
          End Set  
       End Property 
    
       Public ReadOnly Property NumRings() As Integer
          Get
             Return Me.nRings
          End Get   
       End Property 
    
       Public ReadOnly Property SnoozePressed() As Boolean
          Get
             Return Me.pressed
          End Get
       End Property
    End Class
    
    public class AlarmEventArgs : EventArgs 
    {
       private readonly int nRings = 0;
       private readonly bool pressed = false;
       private string text = "The alarm is ringing!";
    
       // Constructor.
       public AlarmEventArgs(bool snoozePressed, int nRings) 
       {
          this.pressed = snoozePressed;
          this.nRings = nRings;
       }
    
       // Properties.
       public string AlarmText {  
          get { return text; }
          set { this.text = value; }
       }
    
       public int NumRings {
          get { return nRings; }
       }
    
       public bool SnoozePressed {
          get { return pressed; }
       }
    }
    
  2. イベントのデリゲートを宣言します。 デリゲートに EventNameEventHandler という名前を付けます。

    Public Delegate Sub AlarmEventHandler(sender As Object, e As AlarmEventArgs)
    
    public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);
    
  3. クラスに EventName という名前のパブリック イベント メンバーを定義します。 イベント メンバーの型にイベント デリゲート型を設定します。

    Public Class AlarmClock
        ' ...
        Public Event Alarm As AlarmEventHandler
    
    End Class
    
    public class AlarmClock 
    {
        // ...
        public event AlarmEventHandler Alarm;
    
    }
    
  4. イベントを発生させるクラスにプロテクト メソッドを定義します。 メソッドに OnEventName という名前を付けます。 このメソッド内で対象のイベントを発生させます。 C# コードでは、イベントを発生させる前にイベントが null かどうかを確認する必要があることに注意してください。 これによって、イベント ハンドラーが関連付けられていない場合にイベントの発生時にスローされる NullReferenceException を処理する必要がなくなります。 この例では、CountDown クラスはイベントを発生させるだけで、それに対するハンドラーは提供しないため、この確認を行う必要があります。

    Public Class AlarmClock
    
        ' ...
        Public Event Alarm As AlarmEventHandler
    
        Protected Overridable Sub OnAlarm(e As AlarmEventArgs)
            RaiseEvent Alarm(Me, e)
        End Sub
    End Class
    
    public class AlarmClock 
    {
        // ...
        public event AlarmEventHandler Alarm;
    
        protected virtual void OnAlarm(AlarmEventArgs e)
        {
          if (Alarm != null) 
              Alarm(this, e); 
        }
    }
    
  5. クラスでいつイベントを発生させるかを決定します。 OnEventName を呼び出してイベントを発生させ、EventNameEventArgs を使用してイベント固有のデータを渡します。

    Public Class AlarmClock
    
        Public Sub Start
            ' ...
            System.Threading.Thread.Sleep(300)
            Dim e As AlarmEventArgs = New AlarmEventArgs(False, 0)
            OnAlarm(e)
        End Sub
    
        Public Event Alarm As AlarmEventHandler
    
        Protected Overridable Sub OnAlarm(e As AlarmEventArgs)
            RaiseEvent Alarm(Me, e)
        End Sub
    End Class
    
    public class AlarmClock 
    {
        public void Start()
        {
            // ...
            System.Threading.Thread.Sleep(300);
            AlarmEventArgs e = new AlarmEventArgs(false, 0);
            OnAlarm(e);
        }
    
        public event AlarmEventHandler Alarm;
    
        protected virtual void OnAlarm(AlarmEventArgs e)
        {
          if (Alarm != null) 
              Alarm(this, e); 
        }
    }
    

使用例

次の例では、ディスクの空き領域が構成ファイルで定義されたパーセント値を下回るたびにイベントを使用して警告を生成する DiskSpaceMonitor クラスを定義します。 さらに、ディスクの空き領域に関するカスタム データをイベント ハンドラーに提供するための DiskSpaceWarningEventArgs クラスも定義します。

Imports System.Collections.Specialized
Imports System.Configuration
Imports System.IO

Public Class DiskSpaceWarningEventArgs : Inherits EventArgs
   Dim currentFreeSpace As Long
   Dim currentTotalSpace As Long
   Dim driveName As String

   Public Sub New(name As String, freeSpace As Long, totalSpace As Long)
      Me.driveName = name
      Me.currentFreeSpace = freeSpace
      Me.currentTotalSpace = totalSpace
   End Sub

   Public ReadOnly Property Name As String
      Get
         Return Me.driveName
      End Get
   End Property

   Public ReadOnly Property FreeSpace As Long
      Get
         Return Me.currentFreeSpace 
      End Get
   End Property

   Public ReadOnly Property TotalSpace As Long
      Get
         Return Me.currentTotalSpace
      End Get
   End Property
End Class

Public Delegate Sub DiskSpaceWarningEventHandler(sender As Object, _
                                                 e As DiskSpaceWarningEventArgs)

Public Class DiskSpaceMonitor
   Public Event DiskSpaceWarning As DiskSpaceWarningEventHandler
   Private threshhold As Decimal 

   Public Sub New()
      ' Retrieve threshhold to fire event from configuration file.
      Try
         Dim settings As NameValueCollection = ConfigurationManager.AppSettings
         Me.threshhold = CDec(settings.Item("Threshhold"))
      ' If there is no configuration file, provide a default value.
      Catch e As ConfigurationErrorsException
         Me.threshhold = 10d
      Catch e As InvalidCastException
         Me.threshhold = 10d
      End Try               
   End Sub

   Public Sub CheckFreeSpace
      ' Get drives present on system.
      Dim drives() As DriveInfo = DriveInfo.GetDrives()
      For Each drive As DriveInfo In drives
         If drive.IsReady Then
            If drive.TotalFreeSpace/drive.TotalSize <= Me.threshhold Then
               OnDiskSpaceWarning(New DiskSpaceWarningEventArgs(drive.Name, _
                                  drive.TotalFreeSpace, drive.TotalSize))
            End If
         End If
      Next   
   End Sub

   Protected Sub OnDiskSpaceWarning(e As DiskSpaceWarningEventArgs)
      RaiseEvent DiskSpaceWarning(me, e)
   End Sub
End Class
using System;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;

public class DiskSpaceWarningEventArgs : EventArgs
{
   private long currentFreeSpace;
   private long currentTotalSpace;
   private string driveName;

   public DiskSpaceWarningEventArgs(string name, long freeSpace, long totalSpace)
   {
      this.driveName = name;
      this.currentFreeSpace = freeSpace;
      this.currentTotalSpace = totalSpace;
   }

   public string Name
   {
      get { return this.driveName; }
   }

   public long FreeSpace
   {
      get { return this.currentFreeSpace; }
   }

   public long TotalSpace
   {
      get { return this.currentTotalSpace; }
   }
}

public delegate void DiskSpaceWarningEventHandler(object sender, 
                                                  DiskSpaceWarningEventArgs e);

public class DiskSpaceMonitor
{
   public event DiskSpaceWarningEventHandler DiskSpaceWarning;
   private decimal threshhold;

   public DiskSpaceMonitor()
   {
      // Retrieve threshhold to fire event from configuration file.
      try
      {
         NameValueCollection settings = ConfigurationManager.AppSettings;
         this.threshhold = Convert.ToDecimal(settings["Threshhold"]);
      }
      // If there is no configuration file, provide a default value.
      catch (ConfigurationErrorsException)
      {
         this.threshhold = 10m;
      }
      catch (InvalidCastException)
      {
         this.threshhold = 10m;
      }
   }

   public void CheckFreeSpace()
   {
      // Get drives present on system.
      DriveInfo[] drives = DriveInfo.GetDrives();
      foreach (DriveInfo drive in drives)
      {
         if (drive.IsReady)
         {
            if (drive.TotalFreeSpace/drive.TotalSize <= this.threshhold)
               OnDiskSpaceWarning(new DiskSpaceWarningEventArgs(drive.Name, 
                                  drive.TotalFreeSpace, drive.TotalSize));
         }
      }
   }

   protected void OnDiskSpaceWarning(DiskSpaceWarningEventArgs e)
   {
      if (DiskSpaceWarning != null)
         DiskSpaceWarning(this, e);
   }   
}

EventArgs クラスを使用してイベント データを提供する代わりに、この例では、DiskSpaceWarningEventArgs という名前のカスタム イベント データ クラスを定義しています。 このクラスはイベント ハンドラーに、ドライブ名、およびドライブで使用できる空き領域と合計領域を提供します。 この例ではさらに、イベント シグネチャを表す DiskSpaceWarningEventHandler というデリゲートも定義しています。

DiskSpaceMonitor クラスは DiskSpaceWarning イベントを定義し、さらに、イベントを発生させる OnDiskSpaceWarning メソッドを提供します。 CheckFreeSpace メソッドによって、ドライブで使用できる空き領域が構成ファイルで定義されたパーセント値以下になったことが検出されると、この OnDiskSpaceWarning メソッドが呼び出されます。

参照

処理手順

方法 : イベントを発生させる/処理する

概念

イベントとデリゲート

イベントの発生

その他の技術情報

イベントの処理と発生