> Manuales > Taller de ASP

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.

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.

Eduardo Noriega de Armas

Manual