JavascriptProva

Visualizzazione post con etichetta Event. Mostra tutti i post
Visualizzazione post con etichetta Event. Mostra tutti i post

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.

Intercettare gli eventi di una classe.

Devo catturare un evento generato da una classe.
Come fare?
Mettiamo in ordine le idee...

Nella classe "mittente" metto questa riga fra le dichiarazioni delle variabili:
Public Event Zum()
(Zum è un nome di fantasia).

...e nel codice dell'evento metto:
   Public Sub evento(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs) Handles motore.SpeechRecognized
       
......

        RaiseEvent Zum()
    End Sub


Nel programma principale dichiaro Withevents l'istanza della classe:
Public Class Form1
    Dim WithEvents mioSpeak As jacSpeak

.....
E nel metodo che voglio evocare in seguito all'evento Zum dell'istanza mioSpeak della classe jacSpeak uso Handles:
    Sub prova() Handles mioSpeak.Zum
        Label1.Text =mioSpeak.risultato
    End Sub
Questo è un primo metodo (che ricordo anche dal VB6), ma non credo proprio che sia l'unico: se l'evento della classe genera un risultato, inoltre, non so come fare, a parte il dichiarare una variabile pubblica della classe che venga modificata dall'evento (in questo caso la variabile Risultato).
Ma non mi sembra una soluzione "estetica"...