Procedura dettagliata: gestione di eventi (Visual Basic)
Questo è il secondo di due argomenti che illustrano come usare gli eventi. Il primo argomento, Procedura dettagliata: Dichiarazione e generazione di eventi, illustra come dichiarare e generare eventi. Questa sezione usa il modulo e la classe di tale procedura dettagliata per illustrare come gestire gli eventi quando si svolgono.
L'esempio di classe Widget
usa istruzioni tradizionali di gestione degli eventi. Visual Basic fornisce altre tecniche per l'uso degli eventi. Per esercizio, è possibile modificare questo esempio per usare le istruzioni AddHandler
e Handles
.
Per gestire l'evento PercentDone della classe Widget
Incollare il codice seguente in
Form1
:Private WithEvents mWidget As Widget Private mblnCancel As Boolean
La parola chiave
WithEvents
specifica che viene usata la variabilemWidget
per gestire gli eventi di un oggetto. Specificare il tipo di oggetto fornendo il nome della classe da cui verrà creato.La variabile
mWidget
viene dichiarata inForm1
perché le variabiliWithEvents
devono essere a livello di classe. Questo vale indipendentemente dal tipo di classe in cui vengono inserite.La variabile
mblnCancel
viene usata per annullare il metodoLongTask
.
Scrittura di codice per gestire un evento
Non appena si dichiara una variabile usando WithEvents
, il nome della variabile viene visualizzato nell'elenco a discesa sinistro dell'editor di codice della classe. Se si seleziona mWidget
, gli eventi della classe Widget
vengono visualizzati nell'elenco a discesa destro. Se si seleziona un evento, viene visualizzata la routine evento corrispondente, con il prefisso mWidget
e un carattere di sottolineatura. A tutte le routine evento associate a una variabile WithEvents
viene assegnato il nome della variabile come prefisso.
Per gestire un evento
Selezionare
mWidget
nell'elenco a discesa sinistro dell'editor di codice.Selezionare l'evento
PercentDone
nell'elenco a discesa destro. Nell'editor di codice verrà visualizzata la routine eventomWidget_PercentDone
.Nota
L'editor di codice è utile, ma non obbligatorio, per l'inserimento di nuovi gestori di eventi. In questa procedura dettagliata risulta più immediato copiare semplicemente i gestori di eventi direttamente nel codice.
Aggiungere il codice seguente al gestore eventi
mWidget_PercentDone
:Private Sub mWidget_PercentDone( ByVal Percent As Single, ByRef Cancel As Boolean ) Handles mWidget.PercentDone lblPercentDone.Text = CInt(100 * Percent) & "%" My.Application.DoEvents() If mblnCancel Then Cancel = True End Sub
Ogni volta che viene generato l'evento
PercentDone
, la routine evento visualizza la percentuale di completamento in un controlloLabel
. Il metodoDoEvents
consente di ridisegnare l'etichetta e offre anche all'utente la possibilità di fare clic sul pulsante Annulla.Aggiungere il codice seguente al gestore di eventi
Button2_Click
:Private Sub Button2_Click( ByVal sender As Object, ByVal e As System.EventArgs ) Handles Button2.Click mblnCancel = True End Sub
Se l'utente fa clic sul pulsante Annulla durante l'esecuzione di LongTask
, l'evento Button2_Click
viene eseguito non appena l'istruzione DoEvents
consente l'elaborazione degli eventi. La variabile mblnCancel
a livello di classe è impostata su True
e l'evento mWidget_PercentDone
lo verifica e imposta l'argomento ByRef Cancel
su True
.
Connessione di una variabile WithEvents a un oggetto
Form1
è ora configurato per gestire gli eventi di un oggetto Widget
. Non rimane altro da fare che trovare un oggetto Widget
.
Quando si dichiara una variabile WithEvents
in fase di progettazione, non viene associato alcun oggetto. Una variabile WithEvents
è identica a qualsiasi altra variabile di oggetto. È necessario creare un oggetto e assegnarvi un riferimento con la variabile WithEvents
.
Per creare un oggetto e assegnarvi un riferimento
Selezionare (Form1 Events) nell'elenco a discesa sinistro dell'editor di codice.
Selezionare l'evento
Load
nell'elenco a discesa destro. Nell'editor di codice verrà visualizzata la routine eventoForm1_Load
.Aggiungere il codice seguente alla routine evento
Form1_Load
per creare l'oggettoWidget
:Private Sub Form1_Load( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles MyBase.Load mWidget = New Widget End Sub
Quando questo codice viene eseguito, Visual Basic crea un oggetto Widget
e ne connette gli eventi alle routine evento associate a mWidget
. Da quel punto in poi, ogni volta che Widget
genera l'evento PercentDone
, viene eseguita la routine evento mWidget_PercentDone
.
Per chiamare il metodo LongTask
Aggiungere il codice seguente al gestore eventi
Button1_Click
:Private Sub Button1_Click( ByVal sender As Object, ByVal e As System.EventArgs ) Handles Button1.Click mblnCancel = False lblPercentDone.Text = "0%" lblPercentDone.Refresh() mWidget.LongTask(12.2, 0.33) If Not mblnCancel Then lblPercentDone.Text = CStr(100) & "%" End Sub
Prima di chiamare il metodo LongTask
, è necessario inizializzare l'etichetta che visualizza la percentuale di collegamento e impostare il flag Boolean
a livello di classe per l'annullamento del metodo su False
.
LongTask
viene chiamato con una durata dell'attività di 12,2 secondi. L'evento PercentDone
viene generato una volta ogni un terzo di secondo. Ogni volta che viene generato l'evento, viene eseguita la routine evento mWidget_PercentDone
.
Al termine di LongTask
, mblnCancel
viene testato per verificare se LongTask
è terminato normalmente o se è stato arrestato perché mblnCancel
è stato impostato su True
. La percentuale di completamento viene aggiornata solo nel primo caso.
Per eseguire il programma
Premere F5 per inserire il progetto in modalità di esecuzione.
Fare clic sul pulsante Avvia attività. Ogni volta che viene generato l'evento
PercentDone
, l'etichetta viene aggiornata con la percentuale di completamento dell'attività.Fare clic sul pulsante Annulla per arrestare l'attività. Si noti che l'aspetto del pulsante Annulla non cambia immediatamente quando viene selezionato. L'evento
Click
non può verificarsi finché l'istruzioneMy.Application.DoEvents
non consente l'elaborazione degli eventi.Nota
Il metodo
My.Application.DoEvents
non elabora gli eventi esattamente allo stesso modo del modulo. In questa procedura dettagliata, ad esempio, è necessario fare clic due volte sul pulsante Annulla. Per consentire al modulo di gestire direttamente gli eventi, si può ricorrere al multithreading. Per altre informazioni, vedere Threading gestito.
Potrebbe essere utile avviare il programma con F11 ed eseguire il codice una riga alla volta. È possibile verificare chiaramente come l'esecuzione entra in LongTask
e quindi brevemente entra in Form1
di nuovo ogni volta che viene generato l'evento PercentDone
.
Cosa succederebbe se, mentre viene eseguito il codice di Form1
, venisse chiamato di nuovo il metodo LongTask
? Nel peggiore dei casi, si potrebbe verificare un overflow dello stack se LongTask
venisse chiamato ogni volta che viene generato l'evento.
È possibile fare in modo che la variabile mWidget
gestisca gli eventi per un oggetto diverso Widget
assegnando un riferimento al nuovo oggetto Widget
a mWidget
. In effetti, è possibile fare in modo che il codice in Button1_Click
esegua questa operazione ogni volta che si fa clic sul pulsante.
Per gestire gli eventi per un widget diverso
Aggiungere la riga di codice seguente alla routine
Button1_Click
, immediatamente prima della rigamWidget.LongTask(12.2, 0.33)
:mWidget = New Widget ' Create a new Widget object.
Il codice precedente crea un nuovo oggetto Widget
ogni volta che si fa clic sul pulsante. Non appena il metodo LongTask
viene completato, il riferimento a Widget
viene rilasciato e l'oggetto Widget
viene eliminato definitivamente.
Una variabile WithEvents
può contenere un solo riferimento a oggetto alla volta, quindi se si assegna un oggetto Widget
diverso a mWidget
, gli eventi dell'oggetto Widget
precedente non verranno più gestiti. Se mWidget
è l'unica variabile oggetto contenente un riferimento al vecchio Widget
, l'oggetto viene eliminato definitivamente. Se si vogliono gestire gli eventi di diversi oggetti Widget
, usare l'istruzione AddHandler
per elaborare gli eventi di ogni oggetto separatamente.
Nota
È possibile dichiarare tutte le variabili WithEvents
necessarie, ma le matrici di variabili WithEvents
non sono supportate.