イベントの利用
更新 : 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 フォーム アプリケーションでイベントを利用する