lunes, 11 de junio de 2012

Añadir eventos de forma dinámica a controles con AddHandler y recibir argumentos con CommandArgument

Debido a una página ASPX en la que estoy trabajando últimamente me he tenido que enfrentar al siguiente problema: una vez cargados un conjunto de registros de pacientes desde una base de datos, quiero mostrar la información concerniente a los mismos, así como un botón que permita eliminar cada registro determinado.

Cuando el número de elementos es fijo y predeterminado, podríamos ser capaces de añadir un manejador de eventos para cada uno de ellos, pero como en este caso al obtener los clientes desde la base de datos y generarlos de forma dinámica, esta solución no es posible.

Para resolver esto pensé que lo más sencillo era generar una serie de Controles de usuario web y asignarles eventos para que respondan al comportamiento deseado, en este caso borrar el registro. La solución es utilizar la instrucción AddHanlder. Dicha instrucción nos permite añadir comportamientos a los objetos que deseemos.

Veamos un poco de código para entenderlo mejor:

For Each pacient As Pacient In list
 Dim strControl = String.Format("{0}", pacient.Titulo)
 Dim control As New LiteralControl(strControl)

 Dim linkButton As New LinkButton()
 linkButton.Text = "Borrar"
 linkButton.CommandArgument = pacient.Id
 AddHandler linkButton.Command, AddressOf Delete

 If paciente.Activo Then
  columnaActivos.Controls.Add(control)
  columnaActivos.Controls.Add(linkButton)
 Else
  columnaInactivos.Controls.Add(control)
  columnaInactivos.Controls.Add(linkButton)
 End If
Next

El código es fácil de comprender, con una lista de pacientes compruebo si cada paciente está activo o no, en función de lo cual se colocará en una u otra columna. Además se le añadirá un LinkButton cuyo texto será Borrar.

En mí caso le he añadido el comportamiento al evento OnCommand, este evento se lanza cuando se hace click en el LinkButton, aunque pertenece a la clase base System.Web.UI.WebControls y se define para cada una de las clases derivadas con un comportamiento, en principio, distinto (en la práctica se suele disparar cuando se hace click).

Este evento nos da la posibilidad de pasar un parámetro adicional, mediante la propiedad CommandArgument del LinkButton, que en mi caso aprovecho para pasar el id del paciente que quiero borrar.

Ahora vamos a ver el método que recibe la invocación al dispararse el evento:

    Private Sub Delete(ByVal sender As Object, ByVal args As CommandEventArgs)
        DeletePacientById(args.CommandArgument)
    End Sub

Es importante que la firma del método coincida con la función delegada del evento OnCommand, de lo contrario se producirá una excepción. Finalmente una vez recibido el evento invocamos al código de borrar desde la base de datos.

A modo de conclusión me gustaría comentar que la instrucción AddHandler no me parece una forma muy intuitiva de añadir comportamientos a los objetos, en estos caso echo de menos la gran flexibilidad que ofrece Javascript en manejo de variables de funciones, que muy pocos lenguajes imperativos ofrecen.

Para acabar quiero mencionar que también existe la instrucción RemoveHandler que permite de forma dinámica, quitar un manejador de eventos a un objeto.

Instrucción AddHandler
http://msdn.microsoft.com/es-es/library/7taxzxka(v=vs.80).aspx

Evento OnCommand:
http://msdn.microsoft.com/es-es/library/system.web.ui.webcontrols.button.oncommand.aspx


No hay comentarios:

Publicar un comentario