JavascriptProva

sabato 7 settembre 2013

Ancora sulla cattura di eventi generati da una classe.

Ecco, ora creo una classe che genera un evento allo scoccare di un certo tempo, mediante un timer.
Imports System.Timers
Public Class Classe
    Private tempo As Timer
    Sub New()
        tempo = New Timer(5000)
        AddHandler tempo.Elapsed, AddressOf metodo
        tempo.Enabled = True

    End Sub
    Sub metodo(ByVal source As Object, ByVal e As ElapsedEventArgs)
        MsgBox("tempo")
    End Sub
End Class


Istanzio:
Public Class Form1
    Dim miaClasse As Classe
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        miaClasse = New Classe

    End Sub
End Class
E funziona. Dopo 5 secondi appare la MessageBox.
L'handler dell'evento timer.elapsed definisce già cosa fare.
Ora io voglio che la classe si limiti a registrare l'evento, lasciando al programma chiamante la decisione del cosa fare.

Riscrivo la classe:
Imports System.Timers
Public Class Classe
    Public Event TimerElapsed()
    Private tempo As Timer
    Sub New()
        tempo = New Timer(5000)
        AddHandler tempo.Elapsed, AddressOf metodo
        tempo.Enabled = True

    End Sub
    Sub metodo(ByVal source As Object, ByVal e As ElapsedEventArgs)
        RaiseEvent TimerElapsed()
    End Sub
End Class
e il programma chiamante:
Public Class Form1
    Dim miaClasse As Classe
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        miaClasse = New Classe
        AddHandler miaClasse.TimerElapsed, AddressOf TempoScaduto
    End Sub
    Sub TempoScaduto()
        MsgBox("tempo")
    End Sub
End Class
E funziona ancora.


Cerchiamo di vedere cosa si intende per delegato, per la precisione: non l'ho ancora capito.
AddHandler è seguito da un evento, e AddressOf da un event handler.

Se invece di usare AddHandler io definisco il gestore dell'evento nel programma chiamante mediante la clausola Handles ottengo un errore:
Public Class Form1
    Dim miaClasse As Classe
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        miaClasse = New Classe
        'AddHandler miaClasse.TimerElapsed, AddressOf TempoScaduto
    End Sub
    Sub TempoScaduto() Handles miaClasse.TimerElapsed
        MsgBox("tempo")
    End Sub
End Class
Ho "commentato" AddHandler, e ho aggiunto la clausola Handles al gestore dell'evento.
Ottengo errore:
Errore 1 La clausola Handles richiede una variabile WithEvents definita nel tipo che la contiene o in uno dei suoi tipi di base. C:\Users\Antonello\Documents\Visual Studio 2010\Projects\laboratorio\laboratorio\Form1.vb 7 32 laboratorio
Devo dichiarare Withevents l'istanza della classe, per usare Handles.
Public Class Form1
    Dim WithEvents miaClasse As Classe
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        miaClasse = New Classe
        'AddHandler miaClasse.TimerElapsed, AddressOf TempoScaduto
    End Sub
    Sub TempoScaduto() Handles miaClasse.TimerElapsed
        MsgBox("tempo")
    End Sub
End Class
Ecco. Così funziona.
Quindi:
  • Per usare AddHandler non è necessario dichiarare l'istanza WithEvents.
  • Per usare la clausola Handles è necessario dichiarare l'istanza WithEvents.

Nessun commento:

Posta un commento