HOW TO:在您的類別中實作事件
下列程序說明如何在類別中實作事件: 第一個程序會實作沒有關聯資料的事件,它使用 System.EventArgs 和 System.EventHandler 類別做為事件資料和委派處理常式。 第二個程序會實作具有自訂資料的事件,它會定義自訂類別做為事件資料和事件委派處理常式。
注意事項 |
---|
本主題顯示如何在類別中宣告和引發事件。其中並不會顯示如何定義使用該事件的事件處理常式。如需如何使用事件的詳細資訊,請參閱使用事件和 HOW TO:引發和使用事件。 |
如需示範引發和處理事件的完整範例,請參閱 HOW TO:引發和使用事件。
若要實作不含事件特定資料的事件
在類別中定義公用事件成員。 將此事件成員的型別設定為 System.EventHandler 委派。
Public Class Countdown ' ... Public Event CountdownCompleted As EventHandler End Class
public class Countdown { // ... public event EventHandler CountdownCompleted; }
在引發事件的類別中提供一個保護的方法。 將此方法命名為 OnEventName。 在方法內引發此事件。 請注意,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); } }
決定何時要在您的類別中引發此事件。 呼叫 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()); } }
若要實作具有事件特定資料的事件
定義提供事件資料的類別。 將此類別命名為 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; } } }
宣告事件的委派。 將委派命名為 EventNameEventHandler。
Public Delegate Sub AlarmEventHandler(sender As Object, e As AlarmEventArgs)
public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);
定義類別中名為 EventName 的公用事件成員。 將此事件成員的型別設定為事件委派型別。
Public Class AlarmClock ' ... Public Event Alarm As AlarmEventHandler End Class
public class AlarmClock { // ... public event AlarmEventHandler Alarm; }
在引發事件的類別中定義一個保護的方法。 將此方法命名為 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); } }
決定何時要在您的類別中引發此事件。 呼叫 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 方法。