Tutorial: Controlar eventos (Visual Basic)

Se trata del segundo de los temas que abordan cómo trabajar con eventos. En el primer tema, Tutorial: declarar y generar eventos, se explica cómo declarar y generar eventos. En esta sección se sigue el formulario y la clase de ese tutorial para exponer cómo se controlan los eventos cuando se producen.

En el ejemplo de clase Widget se recurren a instrucciones tradicionales de control de eventos. Visual Basic ofrece otras técnicas para trabajar con eventos. Pruebe a modificar este ejemplo para usar las instrucciones AddHandler y Handles, como práctica.

Para controlar el evento PercentDone de la clase Widget

  1. Introduzca el código siguiente en Form1:

    Private WithEvents mWidget As Widget
    Private mblnCancel As Boolean
    

    La palabra clave WithEvents especifica que la variable mWidget se usa para controlar los eventos de un objeto. Para especificar el tipo de objeto, proporcione el nombre de la clase a partir de la cual se creará el objeto.

    La variable mWidget se declara en Form1, dado que las variables WithEvents deben ser de nivel de clase. Ocurre esto independientemente del tipo de clase en la que se coloquen.

    La variable mblnCancel se usa para cancelar el método LongTask.

Escribir código para controlar un evento

En cuanto declare una variable por medio de WithEvents, el nombre de la variable aparece en la lista desplegable de la izquierda del Editor de código de la clase. Al seleccionar mWidget, los eventos de la Widget clase aparecen en la lista desplegable de la derecha. Al seleccionar un evento, el procedimiento de evento correspondiente aparece con el prefijo mWidget y un carácter de subrayado. Todos los procedimientos de eventos asociados a una variable WithEvents reciben el nombre de la variable como prefijo.

Para controlar un evento

  1. Seleccione mWidget de la lista desplegable de la izquierda en el Editor de código.

  2. Seleccione el evento PercentDone de la lista desplegable de la derecha. El Editor de código abre el procedimiento del evento mWidget_PercentDone.

    Nota

    El Editor de código es útil, pero no es necesario para insertar nuevos controladores de eventos. En este tutorial. copiar solo los controladores de eventos directamente en el código es una estrategia más directa.

  3. Agregue el código siguiente al controlador de eventos 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
    

    Cada vez que se genera el evento PercentDone, el procedimiento de eventos muestra el porcentaje completo en un control Label. Con el método DoEvents, la etiqueta se puede pintar de nuevo y los usuarios pueden hacer clic en el botón Cancelar.

  4. Agregue el código siguiente para el controlador de eventos Button2_Click:

    Private Sub Button2_Click(
        ByVal sender As Object,
        ByVal e As System.EventArgs
    ) Handles Button2.Click
        mblnCancel = True
    End Sub
    

Si el usuario hace clic en el botón Cancelar, mientras se ejecuta LongTask, el evento Button2_Click se ejecuta tan pronto como la instrucción DoEvents permite que se produzca el procesamiento de eventos. La variable de nivel de clase mblnCancel se establece en True y, a continuación, el evento mWidget_PercentDone lo prueba y establece el argumento ByRef Cancel en True.

Conectar una variable WithEvents a un objeto

Form1 está ahora configurada para controlar los eventos de un objeto Widget. Solo queda encontrar un Widget en algún sitio.

No se asocia ningún objeto a una variable WithEvents cuando se declara en el tiempo de diseño. Una variable WithEvents es igual a cualquier otra variable de objeto. Hay que crear un objeto y asignarle una referencia con la variable WithEvents.

Para crear un objeto y asignarle una referencia

  1. Seleccione (Eventos de Form1) de la lista desplegable de la izquierda en el Editor de código.

  2. Seleccione el evento Load de la lista desplegable de la derecha. El Editor de código abre el procedimiento del evento Form1_Load.

  3. Agregue el código siguiente para que el procedimiento del evento Form1_Load cree el Widget:

    Private Sub Form1_Load(
        ByVal sender As System.Object,
        ByVal e As System.EventArgs
    ) Handles MyBase.Load
        mWidget = New Widget
    End Sub
    

Al ejecutarse este código, Visual Basic crea un objeto Widget y conecta los eventos a los procedimientos de evento asociados a mWidget. Desde ese momento, cada vez que Widget genera el evento PercentDone, se ejecuta el procedimiento de eventos mWidget_PercentDone.

Cómo llamar al método LongTask

  • Agregue el código siguiente al controlador de eventos 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
    

Antes de llamar al método LongTask, hay que inicializar la etiqueta que indica el porcentaje completado y hay que establecer la marca Boolean de nivel de clase para cancelar el método en False.

Se llama a LongTask con una tarea de 12,2 segundos de duración. El evento PercentDone se genera una vez cada tercio de un segundo. Cada vez que se genera el evento, se ejecuta el procedimiento del evento mWidget_PercentDone.

Cuando se completa LongTask, se prueba mblnCancel para ver si LongTask finalizó normalmente o si se detuvo porque se estableció mblnCancel en True. El porcentaje completado solo se actualiza en el caso anterior.

Para ejecutar el programa

  1. Pulse F5 para poner el proyecto en modo de ejecución.

  2. Haga clic en el botón Iniciar tarea. Cada vez que se genera el evento PercentDone, la etiqueta se actualiza con el porcentaje de la tarea que está completa.

  3. Haga clic en el botón Cancelar para detener la tarea. Puede advertir que la apariencia del botón Cancelar no cambia inmediatamente al hacer clic. El evento Click no puede producirse hasta que la instrucción permita el procesamiento de eventos My.Application.DoEvents.

    Nota

    El método My.Application.DoEvents no procesa los eventos exactamente de la misma manera que el formulario. Por ejemplo, en este tutorial, es necesario hacer clic dos veces en el botón Cancelar. Para permitir que el formulario controle directamente los eventos, puede usar multithreading. Para obtener más información, consulte Subprocesamiento administrado.

Es posible que le indique que ejecute el programa con F11 y recorra el código línea por línea. Puede ver con claridad cómo la ejecución introduce LongTask y, a continuación, introduce de nuevo brevemente Form1 cada vez que se genera el evento PercentDone.

¿Qué ocurriría si, mientras la ejecución vuelve al código de Form1, se llamara al método LongTask de nuevo? En el peor de los casos, se produciría un desbordamiento de pila si se llamara a LongTask cada vez que se generara el evento.

Puede hacer que la variable mWidget controle los eventos para un objeto Widget diferente, mediante la asignación de una referencia al nuevo Widget a mWidget. De hecho, puede causar que el código Button1_Click lo haga cada vez que haga clic en el botón.

Cómo controlar los eventos de un widget diferente

  • Agregue la línea de código siguiente al procedimiento Button1_Click, inmediatamente antes de la línea que dice mWidget.LongTask(12.2, 0.33):

    mWidget = New Widget
    ' Create a new Widget object.
    

El código anterior crea un nuevo Widget cada vez que se hace clic. En cuanto se completa el método LongTask, la referencia a Widget se libera y se destruye Widget.

Una variable WithEvents solo puede contener una referencia de objeto a la vez, así que si se asigna un objeto Widget distinto a mWidget, los eventos del objeto Widget anterior dejarán de controlarse. Si mWidget es la única variable de objeto que contiene una referencia al antiguo Widget, el objeto se destruye. Si se quiere controlar los eventos de objetos Widget, use la instrucción AddHandler para procesar eventos de cada objeto por separado.

Nota

Puede declarar tantas variables WithEvents como sean necesarias, pero no se admiten matrices de variables WithEvents.

Consulte también