Sunday, February 24, 2008

[ASP.NET2.0] Extendiendo ASP.NET Server Controls

por Ing. Juan Pablo Ibañez
http://ing.juanpablo.googlepages.com

Muchas veces, al comienzo de nuestra carrera profesional, en la desesperación por programar, nos pasa que nos olvidamos de pensar un poco mas allá de lo que tenemos que hacer justo en este momento y terminamos haciendo las cosas mas de una vez, en otras palabras nos olvidamos de pensar en "reusar". Código duplicado, funcionalidad aquí y allá, nos cuenta mas tiempo y esfuerzo, por lo cual, cuando identificamos una funcionalidad que consideramos que puede ser reusada, lo que debemos hacer es crear un componente que pueda ser usado mas de una vez, documentarlo y agregarlo a nuestra librería de componente.

Para lograr esto, muchas veces lo que debemos hacer extender la funcionalidad de un control de servidor ASP.NET. Por ejemplo, tenemos el control Calendar, pero nos gustaría que cuando pasamos el mouse sobre un día este se pinte de otro color para destacarlo. Esta funcionalidad no la provee el control Calendar clásico de ASP.NET. Podríamos programar la funcionalidad en la misma página donde tenemos agregado el control o podríamos crear un control nuevo con toda la funcionalidad y reusarlo.

Para crear este nuevo control debemos extender la funcionalidad del control Calendar usando el modelo de herencia de ASP.NET.

Lo primero que tenemos que hacer es abrir VisualStudio y crear un proyecto del tipo ASP.NET ServerControl.

Lo que debemos hacer para resolver el problema es crear una clase, la cual llamaremos HoverCalendar, que herede de Calendar, así podemos acceder a toda la funcionalidad de Calendar y agregarle el comportamiento especial que queremos.
El atributo ToolboxData especifica la etiqueta predeterminada generada para un control personalizado cuando éste se arrastra desde un cuadro de herramientas en una herramienta como Microsoft Visual Studio.

Luego dos propiedades, una para el BackColor, la cual llamaremos DayHoverStyleBackgroundColor y otra para el ForeColor, la cual llamaremos DayHoverStyleForeColor, del día sobre4 él cual el mouse esta parado.
Tenemos que tener en cuenta que el valor de estas dos propiedades no sobrevive entre postbacks por lo cual tenemos que guardar estos valores en el ViewState.


El atributo Category especifica el nombre de la categoría en la que se agrupa la propiedad o el evento cuando se muestra en un control de PropertyGrid establecido en el modo por categorías.

El atributo DefaultValue especifica el valor predeterminado de una propiedad.

Ahora lo que debemos hacer es registrar código Javascript para que sea ejecutado cuando se produzcan los eventos onmouseover y onmouseout de cada una de las celdas del calendario.

Cuando el mouse esta sobre un día del calendario el día se debe renderizar con los colores seleccionados en las propiedades DayHoverStyleBackgroundColor y DayHoverStyleForeColor y cuando el mouse sale del día en que estaba se deben volver a renderizar con los coroles que tenia anteriormente.

Para hacer esto nuestro Javascript guarda en 2 variables los colores que tiene el día, renderiza los nuevos y al salir vuelve a cargar los colores guardados en las variables.

Este es el Javacript que necesitamos:

Esta es una función auxiliar usada en la generación del Javascript:
Ahora, para indicarle al control que debe registrar el Javascript en el cliente debemos hacer uso de la clase ClientScriptManager y el momento indicado para hacerlo es cuando se dispara el evento PreRender, por lo cual debemos sobreescribir el metodo OnPreRender indicando que debe registrar el código Javascript ya que este evento es la última oportunidad antes de que se guarde el estado del control en el ViewState y el HTML se generado. O sea que si queremos que el control envíe Javascript al cliente la última oportunidad es aquí.
Bien lo último que queda por hacer es indicar que los eventos onmouseover y onmouseout de las celdas que representan los días del calendario llamen a las funciones que declaramos en nuestro archivo Javascript. Para realizar esta tarea debemos sobreescribir el modo en que se renderizan las celdas para agregarle la funcionalidad nueva, sobreescribiendo el método OnDayRender.



Bueno, con esto tendríamos nuestro control listo.