イベントの利用

更新 : 2007 年 11 月

アプリケーションでイベントを利用するには、イベントに応答してプログラム ロジックを実行するイベント ハンドラ (イベント処理メソッド) を用意し、そのイベント ハンドラをイベント ソースに登録する必要があります。この処理をイベント接続と呼びます。Windows フォーム用および Web フォーム用のビジュアル デザイナには、イベント接続の詳細を簡単にしたり、隠したりするための、RAD (Rapid Application Development) ツールが用意されています。

このトピックでは、イベント処理の一般的なパターンについて説明します。.NET Framework でのイベント モデルの概要については、「イベントとデリゲート」を参照してください。Windows フォームでのイベント モデルの詳細については、「方法 : Windows フォーム アプリケーションでイベントを利用する」を参照してください。Web フォームでのイベント モデルの詳細については、「方法 : Web フォーム アプリケーションでイベントを利用する」を参照してください。

イベント パターン

異なる RAD ツールによって、異なるレベルのサポートが提供されるため、Windows フォームおよび Web フォームでのイベント接続の詳細は異なります。ただし、どちらのシナリオも同じイベント パターンに準拠し、次に示す特徴を持ちます。

  • EventName イベントを発生させるクラスには、次のメンバが属しています。

    public event EventNameEventHandler EventName;
    
    Public Event EventName As EventNameEventHandler
    
  • EventName イベントのイベント デリゲートは EventNameEventHandler で、これは次のシグネチャを持っています。

    public delegate void EventNameEventHandler(object sender, EventNameEventArgs e);
    
    Public Delegate Sub EventNameEventHandler(sender As Object, e As EventNameEventArgs)
    

EventName イベントを利用するには、イベント ハンドラがイベント デリゲートと同じシグネチャを持っている必要があります。

void EventHandler(object sender, EventNameEventArgs e) {}
Sub EventHandler(sender As Object, e As EventNameEventArgs)
メモ :

.NET Framework では、イベント デリゲートは EventNameEventHandler と命名されますが、このドキュメントでは、イベント ハンドラという用語はイベント処理メソッドを意味しています。名前付け方法の基本的な規則により、EventNameEventHandler デリゲートは実際にイベントを処理するイベント ハンドラ (メソッド) を指します。

イベントが関連付けられたデータを持たない場合、イベントを発生させるクラスでは、デリゲートとして System.EventHandler を使用し、イベント データに System.EventArgs を使用します。関連付けられたデータを持つイベントは、イベント データの型の EventArgs から派生したクラスと、それに対応するイベント デリゲート型を使用します。たとえば、Windows フォーム アプリケーションで MouseUp イベントを処理する場合、イベント データ クラスは MouseEventArgs で、イベント デリゲートは MouseEventHandler です。いくつかのマウス イベントは、イベント データの代わりとなる共通のクラスと、共通のイベント デリゲートを使用するため、その名前付け方法は、上で説明した規則と正確には一致しません。マウス イベントの場合、イベント ハンドラは次のシグネチャを持つ必要があります。

void Mouse_Moved(object sender, MouseEventArgs e){}
Sub Mouse_Moved(sender As Object, e As MouseEventArgs)

sender パラメータおよびイベント引数パラメータは、イベント ハンドラにマウス イベントについての詳細情報を提供します。sender オブジェクトは、イベントの発生元を示します。MouseEventArgs パラメータは、イベントを発生させたマウス動作についての詳細情報を提供します。多くのイベント ソースはイベントの詳細データを提供し、多くのイベント ハンドラはイベントを処理する際にイベント固有のデータを使用します。イベント固有のデータを持つイベントを発生させる方法および処理する方法の例については、「方法 : イベントを発生させる/処理する」を参照してください。

メモ :

イベントは、ユーザー インターフェイス (UI: User Interface) 以外のコンテキストでも発生します。実際、.NET Framework には、イベントを発生させる、UI ではないクラスが数多く含まれています。ただし、すべてのイベントはここで説明したパターンに準拠します。

クラスからイベントを発生させる方法については、「イベントの発生」を参照してください。

静的イベントと動的イベント

.NET Framework を使用すると、静的または動的にイベント通知のためのサブスクライバを登録できます。静的なイベント ハンドラは、処理対象のイベントのクラスの有効期間にわたって有効になります。イベント処理では、これが最も一般的なケースです。動的なイベント ハンドラは、プログラムの実行中、通常は条件付きのプログラム ロジックに応答する形で、明示的にアクティブ化または非アクティブ化されます。たとえば、特定の条件下でのみイベント通知が必要な場合や、複数のイベント ハンドラを持つアプリケーションで、実行時の条件に応じて適切なハンドラを決定する場合などに使用できます。

動的なイベント ハンドラを追加するには、EventInfo.AddEventHandler メソッドを使用します。これらのハンドラを非アクティブ化するには、EventInfo.RemoveEventHandler メソッドを使用します。個々の言語には、イベントを動的に処理するための独自の機能が用意されている場合もあります。次の例では、温度が定義済みのしきい値に達したときに TemperatureTheshold イベントを発生させる TemperatureMonitor クラスを定義しています。プログラムの実行中には、このイベントにサブスクライブしているイベント ハンドラのアクティブ化と非アクティブ化が行われます。

public class TemperatureEventArgs : Inherits EventArgs
   Private oldTemp As Decimal
   Private newTemp As Decimal

   Public ReadOnly Property OldTemperature As Decimal
      Get
         Return Me.oldTemp
      End Get   
   End Property

   Public ReadOnly Property NewTemperature As Decimal
      Get
         Return Me.newTemp
      End Get
   End Property

   Public Sub New(oldTemp As Decimal, newTemp As Decimal)
      Me.oldTemp = oldTemp
      Me.newTemp = newTemp   
   End Sub
End Class

Public Delegate Sub TemperatureEventHandler(sender As Object, _
                                            ev As TemperatureEventArgs)

Public Class TemperatureMonitor
   Private currentTemperature As Decimal
   Private threshholdTemperature As Decimal

   Public Event TemperatureThreshold As TemperatureEventHandler 

   Public Sub New(threshHold As Decimal)
      Me.threshholdTemperature = threshHold
   End Sub

   Public Sub SetTemperature(newTemperature As Decimal)
      If (Me.currentTemperature > threshholdTemperature And _
         newTemperature <= Me.threshholdTemperature) Or _
         (Me.CurrentTemperature < Me.threshholdTemperature And _
             newTemperature >= Me.threshholdTemperature) Then
         OnRaiseTemperatureEvent(newTemperature)
      End If
      Me.currentTemperature = newTemperature
   End Sub

   Public Function GetTemperature() As Decimal
      Return Me.currentTemperature
   End Function

   Protected Overridable Sub OnRaiseTemperatureEvent(newTemperature As Decimal)
      RaiseEvent TemperatureThreshold(Me, New TemperatureEventArgs(Me.currentTemperature, _ 
                                       newTemperature))
   End Sub                                       
End Class

Public Module Example
   Public Sub Main()
      Dim tempMon As New TemperatureMonitor(32d)
      tempMon.SetTemperature(33)
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
                        tempMon.GetTemperature())
      tempMon.SetTemperature(32)
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
                        tempMon.GetTemperature())

      ' Add event handler dynamically using Visual Basic syntax.
      AddHandler tempMon.TemperatureThreshold, AddressOf TempMonitor

      tempMon.SetTemperature(33)
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
                        tempMon.GetTemperature())
      tempMon.SetTemperature(34)
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
                        tempMon.GetTemperature())
      tempMon.SetTemperature(32)
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
                        tempMon.GetTemperature())

      ' Remove event handler dynamically using Visual Basic syntax.
      RemoveHandler tempMon.TemperatureThreshold, AddressOf TempMonitor

      tempMon.SetTemperature(31)
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _ 
                        tempMon.GetTemperature())
      tempMon.SetTemperature(35)
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _ 
                        tempMon.GetTemperature())
   End Sub

   Private Sub TempMonitor(sender As Object, e As TemperatureEventArgs)
      Console.WriteLine("   ***Warning: Temperature is changing from {0} to {1}.", _ 
                        e.OldTemperature, e.NewTemperature)
   End Sub 
End Module
' The example displays the following output:
'       Current temperature is 33 degrees Fahrenheit.
'       Current temperature is 32 degrees Fahrenheit.
'       Current temperature is 33 degrees Fahrenheit.
'       Current temperature is 34 degrees Fahrenheit.
'          ***Warning: Temperature is changing from 34 to 32.
'       Current temperature is 32 degrees Fahrenheit.
'       Current temperature is 31 degrees Fahrenheit.
'       Current temperature is 35 degrees Fahrenheit.
using System;

public class TemperatureEventArgs : EventArgs
{
   private decimal oldTemp;
   private decimal newTemp;

   public decimal OldTemperature
   {
      get { return this.oldTemp; }
   }

   public decimal NewTemperature
   {
      get { return this.newTemp; }
   }

   public TemperatureEventArgs(decimal oldTemp, decimal newTemp)
   {
      this.oldTemp = oldTemp;
      this.newTemp = newTemp;   
   }
}

public delegate void TemperatureEventHandler(object sender, TemperatureEventArgs ev);

public class TemperatureMonitor
{
   private decimal currentTemperature;
   private decimal threshholdTemperature;

   public event TemperatureEventHandler TemperatureThreshold; 

   public TemperatureMonitor(decimal threshhold)
   {
      this.threshholdTemperature = threshhold;
   }

   public void SetTemperature(decimal newTemperature)
   {
      if ( (this.currentTemperature > this.threshholdTemperature && 
           newTemperature <= this.threshholdTemperature) ||
           (this.currentTemperature < this.threshholdTemperature &&
           newTemperature >= this.threshholdTemperature) )
         OnRaiseTemperatureEvent(newTemperature);
      this.currentTemperature = newTemperature;
   }

   public decimal GetTemperature()
   {
      return this.currentTemperature;
   }

   protected virtual void OnRaiseTemperatureEvent(decimal newTemperature)
   {
      // Raise the event if it has subscribers.
      if (TemperatureThreshold != null)
         TemperatureThreshold(this, new TemperatureEventArgs(this.currentTemperature, 
                               newTemperature));
   }
}

public class Example
{
   public static void Main()
   {
      Example ex = new Example();
      ex.MonitorTemperatures();
   }

   public void MonitorTemperatures()
   {
      TemperatureMonitor tempMon = new TemperatureMonitor(32);
      tempMon.SetTemperature(33);
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", 
                        tempMon.GetTemperature());
      tempMon.SetTemperature(32);
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
                        tempMon.GetTemperature());

      // Add event handler dynamically using C# syntax.
      tempMon.TemperatureThreshold += this.TempMonitor;

      tempMon.SetTemperature(33);
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", 
                        tempMon.GetTemperature());
      tempMon.SetTemperature(34);
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", 
                        tempMon.GetTemperature());
      tempMon.SetTemperature(32);
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
                        tempMon.GetTemperature());

      // Remove event handler dynamically using C# syntax.
      tempMon.TemperatureThreshold -= this.TempMonitor;

      tempMon.SetTemperature(31);
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", 
                        tempMon.GetTemperature());
      tempMon.SetTemperature(35);
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", 
                        tempMon.GetTemperature());
   }

   private void TempMonitor(object sender, TemperatureEventArgs e)
   {
      Console.WriteLine("   ***Warning: Temperature is changing from {0} to {1}.", 
                        e.OldTemperature, e.NewTemperature);
   } 
}
// The example displays the following output:
//       Current temperature is 33 degrees Fahrenheit.
//       Current temperature is 32 degrees Fahrenheit.
//       Current temperature is 33 degrees Fahrenheit.
//       Current temperature is 34 degrees Fahrenheit.
//          ***Warning: Temperature is changing from 34 to 32.
//       Current temperature is 32 degrees Fahrenheit.
//       Current temperature is 31 degrees Fahrenheit.
//       Current temperature is 35 degrees Fahrenheit.

参照

処理手順

方法 : Web フォーム アプリケーションでイベントを利用する

方法 : Windows フォーム アプリケーションでイベントを利用する

概念

イベントとデリゲート

イベントの発生

その他の技術情報

イベントの処理と発生