Event (Instrucción)

Declara un evento definido por el usuario.

Sintaxis

[ <attrlist> ] [ accessmodifier ] _  
[ Shared ] [ Shadows ] Event eventname[(parameterlist)] _  
[ Implements implementslist ]  
' -or-  
[ <attrlist> ] [ accessmodifier ] _  
[ Shared ] [ Shadows ] Event eventname As delegatename _  
[ Implements implementslist ]  
' -or-  
 [ <attrlist> ] [ accessmodifier ] _  
[ Shared ] [ Shadows ] Custom Event eventname As delegatename _  
[ Implements implementslist ]  
   [ <attrlist> ] AddHandler(ByVal value As delegatename)  
      [ statements ]  
   End AddHandler  
   [ <attrlist> ] RemoveHandler(ByVal value As delegatename)  
      [ statements ]  
   End RemoveHandler  
   [ <attrlist> ] RaiseEvent(delegatesignature)  
      [ statements ]  
   End RaiseEvent  
End Event  

Partes

Parte Descripción
attrlist Opcional. Lista de atributos que se aplican a este evento. Los diversos atributos se separan con comas. Debe incluir la lista de atributos entre corchetes angulares ("<" y ">").
accessmodifier Opcional. Especifica qué código puede tener acceso al evento. Puede ser uno de los siguientes:

- Public: cualquier código con acceso al elemento que lo declara puede tener acceso a él.
- Protected: solo el código de su clase o de una clase derivada puede tener acceso a él.
- Friend: solo el código del mismo ensamblado puede tener acceso a él.
- Private: solo el código del elemento que lo declara puede tener acceso a él.
- Protected Friend: solo el código en la clase del evento, una clase derivada o el mismo ensamblado puede acceder a él.
- Private Protected: solo el código en la clase del evento o una clase derivada el mismo ensamblado puede acceder a él.
Shared Opcional. Especifica que este evento no está asociado a una instancia específica de una clase o estructura.
Shadows Opcional. Indica que este evento vuelve a declarar y oculta un elemento de programación con el mismo nombre, o un conjunto de elementos sobrecargados, en una clase base. Puede reemplazar cualquier tipo de elemento declarado con cualquier otro tipo.

Un elemento reemplazado no está disponible desde la clase derivada que lo reemplaza, excepto desde donde el elemento reemplazado es inaccesible. Por ejemplo, si un elemento Private reemplaza un elemento de clase base, el código que no tiene permiso para acceder al elemento Private accede en su lugar al elemento de clase base.
eventname Necesario. Nombre del evento; sigue las convenciones estándar de nomenclatura de variables.
parameterlist Opcional. Lista de variables locales que representan los parámetros de este evento. Debe incluir la lista de parámetros entre paréntesis.
Implements Opcional. Indica que este evento implementa un evento de una interfaz.
implementslist Es necesario si se proporciona Implements. Lista de procedimientos Sub que se implementan. Los diversos procedimientos se separan con comas:

procedimientoImplementado [ , procedimientoImplementado ... ]

Cada implementedprocedure tiene la sintaxis y las partes siguientes:

interface.definedname

- interface - Obligatorio. Nombre de una interfaz que implementan la estructura o clase contenedora de este procedimiento.
- Definedname - Obligatorio. Nombre por el que se define el procedimiento en interface. No tiene que ser el mismo que name, el nombre que usa este procedimiento para implementar el procedimiento definido.
Custom Necesario. Los eventos declarados como Custom deben definir descriptores de acceso AddHandler, RemoveHandler y RaiseEvent personalizados.
delegatename Opcional. Nombre de un delegado que especifica la firma del controlador de eventos.
AddHandler Necesario. Declara un descriptor de acceso AddHandler, que especifica las instrucciones que se deben ejecutar cuando se agrega un controlador de eventos, ya sea explícitamente mediante la instrucción AddHandler o implícitamente mediante la cláusula Handles.
End AddHandler Necesario. Finaliza el bloque AddHandler.
value Necesario. Nombre del parámetro.
RemoveHandler Necesario. Declara un descriptor de acceso RemoveHandler, que especifica las instrucciones que se ejecutan cuando se quita un controlador de eventos mediante la instrucción RemoveHandler.
End RemoveHandler Necesario. Finaliza el bloque RemoveHandler.
RaiseEvent Necesario. Declara un descriptor de acceso RaiseEvent, que especifica las instrucciones que se ejecutan cuando se produce el evento mediante la instrucción RaiseEvent. Normalmente, invoca una lista de delegados mantenida por los descriptores de acceso AddHandler y RemoveHandler.
End RaiseEvent Necesario. Finaliza el bloque RaiseEvent.
delegatesignature Necesario. Lista de parámetros que coincide con los parámetros requeridos por el delegado delegatename. Debe incluir la lista de parámetros entre paréntesis.
statements Opcional. Instrucciones que contienen los cuerpos de los métodos AddHandler, RemoveHandler y RaiseEvent.
End Event Necesario. Finaliza el bloque Event.

Comentarios

Una vez declarado el evento, use la instrucción RaiseEvent para generar el evento. Un evento típico podría declararse y provocarse tal como se muestra en los fragmentos siguientes:

Public Class EventSource
    ' Declare an event.
    Public Event LogonCompleted(ByVal UserName As String)
    Sub CauseEvent()
        ' Raise an event on successful logon.
        RaiseEvent LogonCompleted("AustinSteele")
    End Sub
End Class

Nota

Puede declarar argumentos de evento del mismo modo que los argumentos de procedimientos, con las siguientes excepciones: los eventos no pueden tener argumentos con nombre, argumentos ParamArray o argumentos Optional. Los eventos no tienen valores devueltos.

Para controlar un evento, debe asociarlo a una subrutina del controlador de eventos mediante la instrucción Handles o AddHandler. Las firmas de la subrutina y del evento deben coincidir. Para controlar un evento compartido, debe usar la instrucción AddHandler.

Solo se puede usar Event en un nivel de módulo. Esto significa que el contexto de la declaración de un evento debe ser una clase, una estructura, un módulo o una interfaz y no puede ser un archivo de código fuente, un espacio de nombres, un procedimiento ni un bloque. Para obtener más información, vea Declaration Contexts and Default Access Levels (Contextos de declaración y niveles de acceso predeterminados).

En la mayoría de los casos, puede usar la primera sintaxis de la sección Sintaxis de este tema para declarar los eventos. Sin embargo, algunos escenarios requieren un mayor control sobre el comportamiento detallado del evento. La última sintaxis de la sección Sintaxis de este tema, que usa la palabra clave Custom, proporciona ese control permitiéndole definir eventos personalizados. En un evento personalizado, debe especificar exactamente lo que sucede cuando el código agrega o quita un controlador de eventos a o desde el evento, o cuando el código provoca el evento. Para obtener ejemplos, consulte Procedimiento para: Declarar eventos personalizados para conservar memoria y Procedimiento para: Declarar eventos personalizados para evitar bloqueos.

Ejemplo

En el ejemplo siguiente se usan eventos para contar los segundos de 10 a 0. El código muestra algunos de los métodos, propiedades e instrucciones relacionados con eventos. Esto incluye la instrucción RaiseEvent.

La clase que provoca un evento es el origen del evento, y los métodos que procesan el evento son los controladores de eventos. Un origen de eventos puede tener varios controladores para los eventos que genera. Cuando la clase genera el evento, ese evento se genera en cada clase que eligió controlar eventos para esa instancia del objeto.

El ejemplo también usa un formulario (Form1) con un botón (Button1) y un cuadro de texto (TextBox1). Al hacer clic en el botón, el primer cuadro de texto muestra una cuenta atrás de 10 a 0 segundos. Cuando transcurre el tiempo (10 segundos), el primer cuadro de texto muestra "Done".

El código de Form1 especifica los estados inicial y terminal del formulario. También contiene el código que se ejecuta cuando se producen eventos.

Para usar este ejemplo, abra un nuevo proyecto de Windows Forms. Agregue un botón denominado Button1 y un cuadro de texto denominado TextBox1 al formulario principal, denominado Form1. Posteriormente, haga clic con el botón derecho en el formulario y haga clic en Ver código para abrir el editor de código.

Agregue una variable WithEvents a la sección de declaraciones de la clase Form1:

Private WithEvents mText As TimerState

Agregue el código siguiente al código de Form1. Sustituya los procedimientos duplicados que existan, como Form_Load o Button_Click.

Private Sub Form1_Load() Handles MyBase.Load
    Button1.Text = "Start"
    mText = New TimerState
End Sub
Private Sub Button1_Click() Handles Button1.Click
    mText.StartCountdown(10.0, 0.1)
End Sub

Private Sub mText_ChangeText() Handles mText.Finished
    TextBox1.Text = "Done"
End Sub

Private Sub mText_UpdateTime(ByVal Countdown As Double
  ) Handles mText.UpdateTime

    TextBox1.Text = Format(Countdown, "##0.0")
    ' Use DoEvents to allow the display to refresh.
    My.Application.DoEvents()
End Sub

Class TimerState
    Public Event UpdateTime(ByVal Countdown As Double)
    Public Event Finished()
    Public Sub StartCountdown(ByVal Duration As Double,
                              ByVal Increment As Double)
        Dim Start As Double = DateAndTime.Timer
        Dim ElapsedTime As Double = 0

        Dim SoFar As Double = 0
        Do While ElapsedTime < Duration
            If ElapsedTime > SoFar + Increment Then
                SoFar += Increment
                RaiseEvent UpdateTime(Duration - SoFar)
            End If
            ElapsedTime = DateAndTime.Timer - Start
        Loop
        RaiseEvent Finished()
    End Sub
End Class

Presione F5 para ejecutar el ejemplo anterior y haga clic en el botón Iniciar. El primer cuadro de texto empieza la cuenta atrás de los segundos. Cuando transcurre el tiempo (10 segundos), el primer cuadro de texto muestra "Done".

Nota

El método My.Application.DoEvents no procesa los eventos de la misma manera que el formulario. Para habilitar el formulario de modo que controle directamente los eventos, puede usar multithreading. Para obtener más información, consulte Subprocesamiento administrado.

Consulte también