Procedura: implementare eventi nella classe
Nelle procedure descritte di seguito viene illustrata l'implementazione di un evento in una classe. Nella prima procedura viene implementato un evento a cui non è associato alcun dato e vengono utilizzate le classi System.EventArgs e System.EventHandler per i dati dell'evento e il gestore delegato. Nella seconda procedura viene implementato un evento con dati personalizzati e vengono definite classi personalizzate relative ai dati dell'evento e al gestore delegato dell'evento.
Nota |
---|
In questo argomento viene illustrato come dichiarare e generare un evento in una classe.Non viene illustrato come definire un gestore dell'evento che utilizzi l'evento.Per ulteriori informazioni sulle modalità di utilizzo degli eventi, vedere Utilizzo degli eventi e Procedura: generare e utilizzare eventi. |
Per un esempio completo in cui viene illustrato come generare e gestire gli eventi, vedere Procedura: generare e utilizzare eventi.
Per implementare un evento senza dati specifici dell'evento
Definire un membro di evento pubblico nella classe. Impostare il tipo del membro di evento su un delegato System.EventHandler.
Public Class Countdown ' ... Public Event CountdownCompleted As EventHandler End Class
public class Countdown { // ... public event EventHandler CountdownCompleted; }
Aggiungere alla propria classe un metodo protetto che generi l'evento. Denominare il metodo OnEventName. Generare l'evento all'interno del metodo. Si noti che tramite il codice C# deve venire eseguito un controllo per determinare se l'evento è Null, prima di generare l'evento. In questo modo, è possibile eliminare la necessità di gestire l'evento NullReferenceException generato nel caso in cui venga generato un evento a cui non sono associati gestori. In questo caso, questo controllo è necessario in quanto la classe CountDown genera semplicemente l'evento ma non fornisce un gestore per tale evento.
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); } }
Determinare quando generare l'evento nella classe. Chiamare OnEventName per generare l'evento.
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()); } }
Per implementare un evento con dati specifici dell'evento
Definire una classe che fornisce i dati per l'evento. Denominare la classe EventNameArgs, derivare la classe da System.EventArgs e aggiungere gli eventuali membri specifici dell'evento.
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; } } }
Dichiarare un delegato per l'evento. Denominare il delegato EventNameEventHandler.
Public Delegate Sub AlarmEventHandler(sender As Object, e As AlarmEventArgs)
public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);
Definire un membro di evento pubblico denominato EventName nella classe. Impostare il tipo del membro di evento sul tipo di delegato dell'evento.
Public Class AlarmClock ' ... Public Event Alarm As AlarmEventHandler End Class
public class AlarmClock { // ... public event AlarmEventHandler Alarm; }
Definire nella classe un metodo protetto che generi l'evento. Denominare il metodo OnEventName. Generare l'evento all'interno del metodo. Si noti che tramite il codice C# deve venire eseguito un controllo per determinare se l'evento è Null, prima di generare l'evento. In questo modo, è possibile eliminare la necessità di gestire l'evento NullReferenceException generato nel caso in cui venga generato un evento a cui non sono associati gestori. In questo caso, questo controllo è necessario in quanto la classe CountDown genera semplicemente l'evento ma non fornisce un gestore per tale evento.
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); } }
Determinare quando generare l'evento nella classe. Chiamare OnEventName per generare l'evento e passare i dati specifici dell'evento mediante 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); } }
Esempio
Nell'esempio seguente viene definita una classe DiskSpaceMonitor che utilizza un evento per generare un avviso ogni volta che lo spazio disponibile su disco scende sotto una percentuale definita in un file di configurazione. Viene inoltre definita una classe DiskSpaceWarningEventArgs per fornire dati personalizzati relativi allo spazio disponibile su disco ai gestori di eventi.
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);
}
}
Anziché utilizzare la classe EventArgs per fornire dati dell'evento, nell'esempio viene definita una classe di dati dell'evento personalizzata denominata DiskSpaceWarningEventArgs. Questa classe indica ai gestori di eventi il nome dell'unità e la quantità di spazio disponibile e totale presente sull'unità. Nell'esempio viene inoltre definito un delegato, DiskSpaceWarningEventHandler, che rappresenta la firma dell'evento.
La classe DiskSpaceMonitor definisce l'evento DiskSpaceWarning e fornisce un metodo OnDiskSpaceWarning che genera l'evento. Il metodo OnDiskSpaceWarning, a sua volta, viene chiamato dal metodo CheckFreeSpace quando viene rilevato che lo spazio disponibile su un'unità è minore o uguale a una percentuale definita in un file di configurazione.
Vedere anche
Attività
Procedura: generare e utilizzare eventi