Como: implementar eventos em sua classe
Os seguintes procedimentos descrevem como implementar um evento em uma classe. O primeiro procedimento implementa um evento que não possui dados associados; ele usa as classes System.EventArgs e System.EventHandler como dados do evento e como manipulador de representante. O segundo procedimento implementa um evento com dados personalizados; ele define classes personalizadas para os dados do evento e o manipulador de representante de evento.
Dica
Este tópico mostra como declarar e dispara um evento em uma classe.Ele mostra como definir um manipulador de eventos que consome o evento.Para obter informações sobre como consumir eventos, consulte Consumindo eventos e Como: gerar e consumir eventos.
Para um exemplo completo que ilustra o surgimento e manipulação de eventos, consulte Como: gerar e consumir eventos.
Para implementar um evento sem dados de eventos específicos
Defina um membro de evento, público, em sua classe. Defina o tipo do membro de evento como um representante de System.EventHandler.
Public Class Countdown ' ... Public Event CountdownCompleted As EventHandler End Class
public class Countdown { // ... public event EventHandler CountdownCompleted; }
Fornece um método protegido na sua classe que lança o evento. Nomeie o método como OnEventName. Lance o evento dentro do método Observe que o código de C# deve verificar para determinar se o evento é nulo antes de disparar o evento. Isso elimina a necessidade de lidar com o NullReferenceException que é lançada quando um evento é gerado, mas sem manipuladores de eventos foram anexadas a ele. Essa verificação é necessária nesse caso porque o CountDown classe simplesmente dispara o evento, mas não fornece um manipulador para ele.
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); } }
Determine quando lançar o evento na sua classe. Chame o método OnEventName para gerar o 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()); } }
Para implementar um evento sem dados de eventos específicos
Defina uma classe que fornece dados para o evento. Nomeie a classe como EventNameArgs, derive a classe de System.EventArgs e adicione todos os membros de eventos específicos.
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; } } }
Declare um representante para o evento. Nomeie o representante como EventNameEventHandler.
Public Delegate Sub AlarmEventHandler(sender As Object, e As AlarmEventArgs)
public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);
Defina um membro de evento, público, denominado EventName na sua classe. Defina o tipo do membro de evento como o tipo de representante de evento.
Public Class AlarmClock ' ... Public Event Alarm As AlarmEventHandler End Class
public class AlarmClock { // ... public event AlarmEventHandler Alarm; }
Define um método protegido na sua classe que lança o evento. Nomeie o método como OnEventName. Lance o evento dentro do método Observe que o código de C# deve verificar para determinar se o evento é nulo antes de disparar o evento. Isso elimina a necessidade de lidar com o NullReferenceException que é lançada quando um evento é gerado, mas sem manipuladores de eventos foram anexadas a ele. Essa verificação é necessária nesse caso porque o CountDown classe simplesmente dispara o evento, mas não fornece um manipulador para ele.
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); } }
Determine quando lançar o evento na sua classe. Chame emEventName para gerar o evento e passar os dados específicos do evento pelo usando 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); } }
Exemplo
O exemplo a seguir define uma DiskSpaceMonitor classe que usa um evento para produzir um aviso sempre que o espaço livre em disco fica abaixo de uma porcentagem que é definida em um arquivo de configuração. Ele também define um DiskSpaceWarningEventArgs classe para fornecer dados personalizados no espaço livre em disco para manipuladores de eventos.
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);
}
}
Em vez de usar o EventArgs da classe para fornecer dados de evento, o exemplo define uma classe de dados de evento personalizado chamada DiskSpaceWarningEventArgs. Ele fornece manipuladores de eventos com o nome da unidade, bem como a quantidade de espaço livre e total disponível na unidade. O exemplo também define um delegado, DiskSpaceWarningEventHandler, que representa a assinatura do evento.
O DiskSpaceMonitor classe define o DiskSpaceWarning eventos e também fornece um OnDiskSpaceWarning método dispara o evento. O OnDiskSpaceWarning método é, por sua vez, chamado pelo CheckFreeSpace método quando ele detecta que o espaço livre disponível em uma unidade é menor ou igual a uma porcentagem que é definida em um arquivo de configuração.
Consulte também
Tarefas
Como: gerar e consumir eventos