Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo illustra come usare eventi in .NET usando il EventHandler delegato, il EventHandler<TEventArgs> delegato e un delegato personalizzato, con esempi per gli eventi con e senza dati.
Prerequisiti
Acquisire familiarità con i concetti descritti nell'articolo Eventi .
Generare un evento senza dati
Questi passaggi creano una Counter classe che genera un ThresholdReached evento quando un conteggio progressivo raggiunge o supera una soglia.
Dichiara l'evento usando il EventHandler delegate.
Usare
EventHandlerquando l'evento non passa i dati al gestore:public event EventHandler? ThresholdReached;Public Event ThresholdReached As EventHandlerAggiungere un
protected virtualmetodo (Protected Overridablein Visual Basic) per generare l'evento.Questo modello consente alle classi derivate di eseguire l'override del comportamento di generazione degli eventi senza richiamare direttamente il delegato. In C#, usare l'operatore condizionale Null (
?.) per evitare che non vi sia alcun sottoscrittore (in Visual Basic,RaiseEventgestisce automaticamente):protected virtual void OnThresholdReached(EventArgs e) { ThresholdReached?.Invoke(this, e); }Protected Overridable Sub OnThresholdReached(e As EventArgs) RaiseEvent ThresholdReached(Me, e) End SubChiama il metodo raise quando la condizione è soddisfatta.
Pass Empty perché questo evento non contiene dati:
if (_total >= _threshold) { OnThresholdReached(EventArgs.Empty); }If (_total >= _threshold) Then OnThresholdReached(EventArgs.Empty) End IfSottoscrivere l'evento usando l'operatore
+=(in Visual Basic,AddHandler):c.ThresholdReached += c_ThresholdReached;AddHandler c.ThresholdReached, AddressOf c_ThresholdReachedDefinire il metodo del gestore eventi.
La firma deve corrispondere al EventHandler delegato, ovvero il primo parametro è l'origine evento e il secondo è EventArgs:
static void c_ThresholdReached(object? sender, EventArgs e) { Console.WriteLine("The threshold was reached."); Environment.Exit(0); }Sub c_ThresholdReached(sender As Object, e As EventArgs) Console.WriteLine("The threshold was reached.") Environment.Exit(0) End Sub
L'esempio seguente illustra l'implementazione completa:
class EventNoData
{
static void Main()
{
Counter c = new(new Random().Next(10));
c.ThresholdReached += c_ThresholdReached;
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
static void c_ThresholdReached(object? sender, EventArgs e)
{
Console.WriteLine("The threshold was reached.");
Environment.Exit(0);
}
}
class Counter(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
if (_total >= _threshold)
{
OnThresholdReached(EventArgs.Empty);
}
}
protected virtual void OnThresholdReached(EventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
public event EventHandler? ThresholdReached;
}
Module EventNoData
Sub Main()
Dim c As New Counter(New Random().Next(10))
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
Sub c_ThresholdReached(sender As Object, e As EventArgs)
Console.WriteLine("The threshold was reached.")
Environment.Exit(0)
End Sub
End Module
Class Counter
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
If (_total >= _threshold) Then
OnThresholdReached(EventArgs.Empty)
End If
End Sub
Protected Overridable Sub OnThresholdReached(e As EventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
Public Event ThresholdReached As EventHandler
End Class
Generare un evento con dati
Questi passaggi estendono l'esempio precedente Counter per generare un evento che include i dati, ovvero il valore soglia e il momento in cui è stato raggiunto.
Definire una classe di dati di evento che eredita da EventArgs.
Aggiungere proprietà per ogni porzione di dati da passare al gestore:
public class ThresholdReachedEventArgs : EventArgs { public int Threshold { get; set; } public DateTime TimeReached { get; set; } }Class ThresholdReachedEventArgs Inherits EventArgs Public Property Threshold As Integer Public Property TimeReached As Date End ClassDichiara l'evento usando il delegato EventHandler<TEventArgs>, passando la classe di dati dell'evento come argomento di tipo:
public event EventHandler<ThresholdReachedEventArgs>? ThresholdReached;Public Event ThresholdReached As EventHandler(Of ThresholdReachedEventArgs)Aggiungere un
protected virtualmetodo (Protected Overridablein Visual Basic) per generare l'evento.Questo modello consente alle classi derivate di eseguire l'override del comportamento di generazione degli eventi senza richiamare direttamente il delegato. In C#, usare l'operatore condizionale Null (
?.) per evitare che non vi sia alcun sottoscrittore (in Visual Basic,RaiseEventgestisce automaticamente):protected virtual void OnThresholdReached(ThresholdReachedEventArgs e) { ThresholdReached?.Invoke(this, e); }Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs) RaiseEvent ThresholdReached(Me, e) End SubPopolare l'oggetto dati dell'evento e chiamare il metodo raise quando viene soddisfatta la condizione:
if (_total >= _threshold) { ThresholdReachedEventArgs args = new ThresholdReachedEventArgs(); args.Threshold = _threshold; args.TimeReached = DateTime.Now; OnThresholdReached(args); }If (_total >= _threshold) Then Dim args As New ThresholdReachedEventArgs With { .Threshold = _threshold, .TimeReached = Date.Now } OnThresholdReached(args) End IfSottoscrivere l'evento usando l'operatore
+=(in Visual Basic,AddHandler):c.ThresholdReached += c_ThresholdReached;AddHandler c.ThresholdReached, AddressOf c_ThresholdReachedDefinire il gestore eventi.
Il secondo tipo di parametro è
ThresholdReachedEventArgsinvece di EventArgs, che consente al gestore di leggere i dati dell'evento:static void c_ThresholdReached(object? sender, ThresholdReachedEventArgs e) { Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}."); Environment.Exit(0); }Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs) Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached) Environment.Exit(0) End Sub
L'esempio seguente illustra l'implementazione completa:
class EventWithData
{
static void Main()
{
CounterWithData c = new(new Random().Next(10));
c.ThresholdReached += c_ThresholdReached;
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
static void c_ThresholdReached(object? sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
}
class CounterWithData(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
}
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
public event EventHandler<ThresholdReachedEventArgs>? ThresholdReached;
}
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
Module EventWithData
Sub Main()
Dim c As New CounterWithData(New Random().Next(10))
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
End Module
Class CounterWithData
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
End Sub
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
Public Event ThresholdReached As EventHandler(Of ThresholdReachedEventArgs)
End Class
Class ThresholdReachedEventArgs
Inherits EventArgs
Public Property Threshold As Integer
Public Property TimeReached As Date
End Class
Dichiarare un delegato personalizzato per un evento
Dichiarare un delegato personalizzato solo in rari scenari, ad esempio per rendere la classe compatibile con il codice legacy che non può usare tipi generici. Per la maggior parte dei casi, usare EventHandler<TEventArgs> come illustrato nella sezione precedente.
Dichiarare il tipo di delegato personalizzato.
La firma del delegato deve corrispondere alla firma del gestore eventi: due parametri: l'origine evento (
object; in Visual Basic,Object) e la classe di dati dell'evento:public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)Dichiarare l'evento usando il tipo di delegato personalizzato anziché EventHandler<TEventArgs>:
public event ThresholdReachedEventHandler? ThresholdReached;Public Event ThresholdReached As ThresholdReachedEventHandlerAggiungere un
protected virtualmetodo (Protected Overridablein Visual Basic) per generare l'evento.In C#, usare l'operatore condizionale Null (
?.) per evitare che non vi sia alcun sottoscrittore (in Visual Basic,RaiseEventgestisce automaticamente):protected virtual void OnThresholdReached(ThresholdReachedEventArgs e) { ThresholdReached?.Invoke(this, e); }Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs) RaiseEvent ThresholdReached(Me, e) End SubRiempire l'oggetto dati dell'evento e chiamare il metodo raise quando viene soddisfatta la condizione.
if (_total >= _threshold) { ThresholdReachedEventArgs args = new(); args.Threshold = _threshold; args.TimeReached = DateTime.Now; OnThresholdReached(args); }If (_total >= _threshold) Then Dim args As New ThresholdReachedEventArgs With { .Threshold = _threshold, .TimeReached = Date.Now } OnThresholdReached(args) End IfSottoscrivere l'evento usando l'operatore
+=(in Visual Basic,AddHandler):c.ThresholdReached += c_ThresholdReached;AddHandler c.ThresholdReached, AddressOf c_ThresholdReachedDefinire il gestore eventi.
La firma del gestore deve corrispondere al delegato personalizzato,
objectper il mittente e la classe di dati dell'evento per il secondo parametro:static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e) { Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}."); Environment.Exit(0); }Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs) Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached) Environment.Exit(0) End Sub
L'esempio seguente illustra l'implementazione completa:
class EventWithDelegate
{
static void Main()
{
CounterWithDelegate c = new(new Random().Next(10));
c.ThresholdReached += c_ThresholdReached;
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
}
class CounterWithDelegate(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
}
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
public event ThresholdReachedEventHandler? ThresholdReached;
}
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);
Module EventWithDelegate
Sub Main()
Dim c As New CounterWithDelegate(New Random().Next(10))
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
End Module
Class CounterWithDelegate
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
End Sub
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
Public Event ThresholdReached As ThresholdReachedEventHandler
End Class
Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)