Utilizzo degli eventi

Per utilizzare un evento in un'applicazione, occorre predisporre un metodo per la gestione eventi che esegua una logica di programma in risposta all'evento. Occorre inoltre registrare il gestore eventi presso l'origine evento. Si fa riferimento a questa operazione come a un collegamento evento. Nelle finestre di progettazione visiva di Windows Form e Web Form sono disponibili strumenti per lo sviluppo rapido di applicazioni (RAD, Rapid Application Development) che semplificano o nascondono i dettagli del collegamento eventi.

In questo argomento viene descritto il modello generale per la gestione degli eventi. Per una panoramica del modello eventi adottato da .NET Framework, vedere Eventi e delegati. Per ulteriori informazioni sul modello eventi in Windows Form, vedere Procedura: utilizzare eventi in un'applicazione Windows Form. Per ulteriori informazioni sul modello eventi in Web Form, vedere Procedura: utilizzare eventi in un'applicazione Web Form.

Il modello eventi

I dettagli sul collegamento degli eventi presentano delle differenze in Windows Form e Web Form a causa dei livelli differenti di supporto offerto dai diversi strumenti RAD. Tuttavia entrambi gli scenari seguono lo stesso modello di eventi, che presenta le caratteristiche seguenti:

  • Una classe che genera un evento denominato EventName include il membro seguente:
Public Event EventName As EventNameEventHandler
public event EventNameEventHandler EventName;
public:
    event EventNameEventHandler^ EventName;
  • Il delegato dell'evento EventName è EventNameEventHandler, con la firma seguente:
Public Delegate Sub EventNameEventHandler(sender As Object, e As EventNameEventArgs)
public delegate void EventNameEventHandler(object sender, EventNameEventArgs e);
delegate void EventNameEventHandler(Object^ sender, EventNameEventArgs^ e);

Per utilizzare l'evento EventName, è necessario che il gestore eventi abbia la stessa firma del delegato dell'evento:

Sub EventHandler(sender As Object, e As EventNameEventArgs)
End Sub
void EventHandler(object sender, EventNameEventArgs e) {}
void EventHandler(Object^ sender, EventNameEventArgs^ e) {}

Nota

In .NET Framework il nome del delegato dell'evento rispetta la sintassi EventNameEventHandler, mentre nella documentazione il termine gestore eventi si riferisce a un metodo per la gestione degli eventi.La logica alla base di tale schema di denominazione è che un delegato EventNameEventHandler punta al gestore eventi (il metodo) che effettivamente gestisce l'evento.

Quando a un evento non è associato alcun dato, la classe che genera l'evento utilizza System.EventHandler come delegato e System.EventArgs per i dati dell'evento. Gli eventi a cui sono associati dati utilizzano classi che derivano da EventArgs per il tipo di dati dell'evento e il tipo di delegato dell'evento corrispondente. Se, ad esempio, si desidera gestire un evento MouseUp in un'applicazione Windows Form, la classe dei dati dell'evento sarà MouseEventArgs e il delegato dell'evento sarà MouseEventHandler. Si noti che diversi eventi del mouse utilizzano una classe comune per i dati evento e un delegato di evento comune, pertanto il criterio di denominazione non corrisponde esattamente a quello sopra descritto. Per gli eventi del mouse, è necessario che il gestore eventi presenti la firma seguente:

Sub Mouse_Moved(sender As Object, e As MouseEventArgs)
End Sub
void Mouse_Moved(object sender, MouseEventArgs e){}
void Mouse_Moved(Object^ sender, MouseEventArgs^ e){}

I parametri del mittente e dell'argomento evento forniscono ulteriori dettagli sull'evento mouse al gestore eventi. L'oggetto mittente indica cosa ha generato l'evento. Il parametro MouseEventArgs fornisce dettagli sul movimento del mouse che ha generato l'evento. Molte origini eventi forniscono dati aggiuntivi relativi all'evento e numerosi gestori eventi utilizzano i dati specifici dell'evento per elaborare l'evento. Per un esempio in cui vengono illustrate la generazione e la gestione di eventi con dati specifici dell'evento, vedere Procedura: generare e utilizzare eventi.

Nota

Gli eventi vengono anche generati all'esterno del contesto delle interfacce utente (UI, User Interface). .NET Framework, infatti, include numerose classi non UI che generano eventi.Tutti gli eventi seguono comunque il modello appena descritto.

Per informazioni su come generare eventi da una classe, vedere Generazione di un evento.

Eventi statici e dinamici

.NET Framework consente ai sottoscrittori di registrarsi per le notifiche di eventi in modo statico o dinamico. I gestori eventi statici hanno effetto per l'intera durata della classe di cui possono gestire gli eventi. Si tratta del metodo più diffuso di gestione degli eventi. I gestori eventi dinamici vengono attivati e disattivati in modo esplicito durante l'esecuzione del programma, in genere in risposta a una logica di programma condizionale. Ad esempio, possono essere utilizzati se le notifiche di eventi sono necessarie solo in determinate condizioni oppure se l'applicazione fornisce più gestori eventi e le condizioni di runtime definiscono quello appropriato da utilizzare.

Il metodo EventInfo.AddEventHandler aggiunge gestori eventi dinamici e il metodo EventInfo.RemoveEventHandler li disattiva. Nei singoli linguaggi sono disponibili funzionalità specifiche per la gestione dinamica degli eventi. Nell'esempio seguente viene definita una classe TemperatureMonitor che genera un evento TemperatureTheshold ogni volta che la temperatura raggiunge una soglia predefinita. Durante l'esecuzione del programma, viene quindi attivato e disattivato un gestore eventi che sottoscrive questo evento.

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.

Vedere anche

Attività

Procedura: utilizzare eventi in un'applicazione Web Form

Procedura: utilizzare eventi in un'applicazione Windows Form

Concetti

Eventi e delegati

Generazione di un evento

Altre risorse

Gestione e generazione di eventi