Generando eventos en la Master
Page.
Por: Eduardo Noriega de Armas
A través del siguiente artículo, mostramos cómo podemos comunicar la Master Page
o Página Maestra con la Content Page o Página de Contenido, logrando que la
Página de Contenido pueda acceder a los diferentes controles colocados en la
Página Maestra y pueda cambiarle su estado, así como enterarse cuando se ha
generado algún evento sobre alguno de esos controles y darle una respuesta.
Una de las funcionalidades añadidas al
ASP.NET 2.0 es el manejo de plantillas como parte de la creación de nuestras
páginas. Estas plantillas, conocidas como Páginas Maestras o Master Pages, nos
permiten crear un diseño que será compartido por otras muchas páginas de nuestro
sitio a las que llamaremos Páginas de Contenido o Content Pages. Lo interesante
es que las Master Pages no solo contendrán la apariencia visual que compartirán
otras muchas páginas, sino que también contendrán el comportamiento. Es decir,
en nuestras Master Pages podemos colocar controles como botones, combos, etc. Y
todos los eventos que implementemos para esos controles, quedarán implementados
para todas las Content Pages que utilicen la Master Page.
No es interés de este artículo mostrar
cómo crear una Master Page. Existen infinidad de artículos en Internet que
explican cómo hacerlo. El objetivo de este trabajo es mostrar cómo podemos
relacionar nuestra Master Page con las diferentes Content Pages y cómo pasar
eventos entre ellas.
Comencemos creando una aplicación que
nos permita ejemplificar todo esto.
Supongamos que deseamos que un grupo
de nuestras páginas tenga un botón y una etiqueta. Para lograrlo, colocaremos
ese botón y esa etiqueta en una Master Page. Supongamos que deseamos que cada
página que use la Master
Page, pueda colocar en la etiqueta el texto que desee y que ese
texto se coloque cuando se presione el botón Refrescar colocado en la Master Page.
Hagámoslo.
Vamos a partir con que tenemos un
proyecto web lo mismo en el Visual Studio 2005 que en el Visual Web Developer.
En ese proyecto creamos una carpeta llamada Master y dentro de ella colocamos
una Master Page a la que llamamos Ejemplo.master.
En nuestra plantilla vamos a colocar
una tabla que contenga un botón Refrescar cuyo ID es btnRefrescar, un label con
ID lblTexto y el ContentPlaceHolder donde las Content Pages que utilicen esta
Master Page colocarán sus contenidos.
La Figura 1 muestra cómo se vería
nuestro proyecto hasta aquí.

Ahora necesitamos que una Content Page
pueda acceder al label lblTexto para que pueda modificar su información.
Para eso, borremos la página
Default.aspx que se nos crea por defecto cuando construimos el proyecto, y
agreguemos una nueva WebForm, a la que llamemos Default.aspx. y en su creación
digamos que utilice la
Master Page que hemos creado.
Una vez hecho esto, el Visual Studio
se vería tal y como muestra la Figura 2.

Ahora desearíamos poder acceder, desde
la página Default.aspx al label que colocamos en la Master Page, para poder
modificarle el texto. Tratemos de hacer ese acceso, desde el método Page_Load de
la página.
Nuestra página por defecto va a tener
una propiedad llamada Master, que es una referencia a la Master Page que
utiliza. A través de esa propiedad podemos acceder a cualquier control colocado
en la página maestra, utilizando el método FindControl que nos ofrece la
MasterPage. El método Page_Load de nuestra página Default.aspx podría quedar de
la siguiente manera:
Protected Sub
Page_Load(...) Handles
Me.Load
CType(Master.FindControl("lblTexto"), Label).Text = "Ejemplo"
End Sub
|
No obstante, podemos usar otra vía
para acceder al label directamente, sin tener que buscarlo. Para lograrlo,
tenemos el inconveniente de que el label es un campo protegido de la Master
Page, por lo que para accederlo tenemos que añadirle a nuestra página maestra,
una propiedad pública a través de la cual accedamos al label. El código de
nuestra Master Page nos podría quedar de la siguiente manera:
| Partial Class
Master_Ejemplo
Inherits
System.Web.UI.MasterPage
Public ReadOnly Property LabelTexto()
As Label
Get
Return
Me.lblTexto
End
Get
End Property
End Class
|
Una vez hecho eso, es muy fácil
acceder desde nuestra página Default.aspx, al label de la página maestra,
utilizando la propiedad Master que nuestra página tiene. Para eso, solo tenemos
que hacerle un casting a la propiedad Master, de tal forma que la veamos como
una Master_Ejemplo, que es el tipo real de nuestra Master Page y de esa manera
poder acceder a la nueva propiedad creada por nosotros.
El método Page_Load de nuestra página
Default.aspx podría quedar como sigue.
Protected Sub
Page_Load(...) Handles
Me.Load
CType
(Me.Master, Master_Ejemplo).LabelTexto.Text =
"Ejemplo"
End
Sub
|
No obstante, podemos evitarnos el
casting, si indicamos el tipo a través de la siguiente directiva <%@ MasterType VirtualPath="~/Master/Ejemplo.master" %>
Es decir, debemos colocar esa
directiva al inicio de nuestra página Default.aspx, para poder acceder a la
nueva propiedad LabelTexto directamente desde la variable Master.
El documento Default.aspx quedaría con
el siguiente contenido:
<%@
Page Language="VB" MasterPageFile="~/Master/Ejemplo.master" ... %>
<%@
MasterType VirtualPath="~/Master/Ejemplo.master" %>
<asp:Content ID="Content1"
...>
</asp:Content>
Y el código de su método Page_Load
quedaría de la siguiente manera:
Protected Sub
Page_Load(...) Handles
Me.Load
Master.LabelTexto.Text =
"Ejemplo"
End Sub
|
Sin embargo, lo ideal sería que
valorizáramos el label no en el Page_Load de la página, sino como resultado del
OnClick del botón que colocamos en la MasterPage. La pregunta entonces es: ¿Cómo
lograr que nuestra página se entere de un evento que se está generando en la
Master Page? La respuesta a esta pregunta la encontraremos en el uso de los
Eventos.
Añadamos a nuestra clase
Master_Ejemplo, es decir, a nuestra Master Page, un evento público al que
llamemos Refrescar_Click y que sea del tipo EventHandler. Este tipo EventHandler
no es más que un delegado de la biblioteca de clases de .NET que se encuentra en
el espacio de nombre System.
Una vez que hemos creado el evento,
añadamos a nuestra Master Page un método btnRefrescar_Click que manipule el
evento Click del botón Refrescar y dentro de ese método, simplemente lancemos el
evento Refrescar_Click que hemos creado.
Resumiendo. Nuestra intensión es
colocar un evento público en nuestra página maestra, al que se puedan registrar
todas las páginas que usen esa Master Page. Esas páginas entonces, registrarán
métodos a ese evento, de tal forma que cuando la Master Page genere el evento,
como resultado del OnClick del botón, las otras páginas se enteren y puedan
realizar alguna acción al respecto, como puede ser, cambiar el texto del label.
Finalmente el código de nuestra Master
Page quedaría de la siguiente manera.
| Partial Class
Master_Ejemplo
Inherits
System.Web.UI.MasterPage
Public Event Refrescar_Click As
EventHandler
Public ReadOnly Property LabelTexto()
As Label
Get
Return
Me.lblTexto
End
Get
End Property
Protected
Sub btnRefrescar_Click(...)
Handles btnRefrescar.Click
RaiseEvent
Refrescar_Click(sender, e)
End Sub
End Class
|
Solo nos queda por hacer un pequeño
ajuste para que desde nuestra página Default.aspx podamos escuchar el evento
Refrescar_Click de la página maestra.
Sucede que la propiedad Master que
tenemos en nuestra página Default.aspx, no fue declarada con la palabra
reservada WithEvents. Debemos entonces crear un nuevo campo en nuestra clase a
través del cual manipulemos los eventos generados en la Master Page. Ese campo
debe tener el modificador WithEvents y lo podemos crear del tipo Master_Ejemplo.
En el Page_Load de la página le asignaríamos a este nuevo campo, el valor del
campo Master que ya teníamos, y con eso ya podemos manipular los eventos.
El código de nuestra página nos
quedaría de la siguiente manera:
Partial Class
_Default
Inherits
System.Web.UI.Page
Protected
WithEvents MyMaster As
Master_Ejemplo
Protected
Sub Page_Load(...) Handles Me.Load
MyMaster = Master
End Sub
Protected Sub
MyMaster_Refrescar_Click(...)
Handles MyMaster.Refrescar_Click
Master.LabelTexto.Text = "Ejemplo"
End Sub
End Class
|
Si echamos a correr la aplicación y le
damos click al botón Refrescar, veremos como se muestra el texto “Ejemplo”
Conclusión
En este artículo hemos visto cómo
acceder desde cualquier página a los diferentes controles contenidos en la
Master Page y sobre todo, como implementar los diferentes eventos que en ella se
puedan generar.