Control personalizado ASP.NET HyperLinkHtmlToolTip
Extensión del objeto System.Web.UI.WebControl.HyperLink para agregar funcionalidad de presentación visual con contenido Html cuando el usuario pasa el ratón sobre el control

Fecha: 27/Oct/2004 (25/Oct/2004)
Autor: Haaron Gonzalez, e-mail: haarongonzalez@hotmail.com,
weblog: http://weblogs.golemproject.com/hgonzalez/

 


Introducción

Continuando con la serie de artículos sencillos pero espero útiles sobre controles de servidor personalizados hoy hablaremos sobre la capacidad de mostrar ToolTips con grandes capacidades de formato ya que se utilizara Html, esto es debido a que actualmente la propiedad ToolTip nos muestra en un cuadrito amarillo el dato que especifiquemos, por ejemplo:

Y en determinado momento el usuario puede dejar pasar desapercibido el mensaje, lo que haremos en este artículo es extender la funcionalidad del control System.Web.UI.WebControl.HyperLink para mostrar un mensaje ToolTip basados en Html rico en su contenido y con el fin de llamar la atención del usuario cuando pasa el ratón sobre el control.

Pero antes de continuar, si aun no has visto los artículos anteriores, aquí esta la lista:

La Solución

Para fines prácticos y de seguimiento utilizaremos la solución y proyectos creados en los artículos de esta serie mencionados anteriormente así que si no cuentas con ello empieza por ahí y cuando termines deberás contar con la siguiente estructura:

Selecciona el proyecto ControlesWeb creamos una clase de nombre:  HyperLinkHtmlToolTip y escribimos las siguientes secciones de código:   

NOTA: Debido a lo extenso del código que manejaremos para este artículo se procedió a especificar un breve comentario y una región en donde staremos clasificando en regiones el código.

En la región "Miembros privados" escribimos las variables privadas de la clases que sostendrán la información especificada por el usuario.

Imports System.ComponentModel
Imports System.Web.UI.WebControls

Public Class HyperLinkHtmlToolTip 
    Inherits HyperLink

#Region "Miembros privados" 
    ' sostiene el nombre de la clase Css por default es nada 
    Private mstrCssHtmlToolTipStyle As String = String.Empty

    ' sostiene el texto html que deseamos mostrar en el HtmlToolTip 
    Private mstrToolTipTextoHtml As String = String.Empty

    ' sostiene el estilo predeterminado del HtmlToolTip 
    Private mstrToolTipStyle As String = "display: none; position: absolute; font-size: 10px; color: black;font-family: Verdana, Arial, Helvetica, sans-serif; background-color: beige;"

     ' sostiene el valor en segundos de la HtmlToolTip 
    Private mintSegundo As Integer = 4

#End Region

Las propiedades públicas que manejaremos cuentan con el identificador <Bindable(True)> de la clase System.ComponentModel, este identificador nos sirve para especificar que esta propiedad podra ser vinculada desde cualquier origen de datos, asi que podemos contruir en nuestra base de datos el codigo Html y regresarlo a esta propiedad para que lo despligue, continuemos con la siguiente sección de código. 

#Region "Propiedades publicas"

    'por medio de esta propiedad se especifican los segundos de duracion del HtmlToolTip
    <Description("Duración en segundos del HtmlToolTip mostrado")> _
        Property ToolTipHtmlDuration() As Integer
        Get
           Return mintSegundo
        End Get
        Set(ByVal value As Integer)
            mintSegundo = value
        End Set
    End Property

    ' por medio de esta propiedad especificamos el nombre de la clase Css que define el estilo de presentacion
    <Bindable(True), Description("Identificador Cascade Style Sheet")> _
    Property ToolTipHtmlCss() As String
       Get
            Return mstrCssHtmlToolTipStyle
       End Get
        Set(ByVal Value As String)
            mstrCssHtmlToolTipStyle = Value
        End Set
    End Property

    ' por medio de esta propiedad podemos declarar directamente el estilo del HtmlToolTip
    <Bindable(True), Description("Propiedad Style de HTML para definir declarativamente la presentación")> _
    Property ToolTipHtmlStyle() As String
        Get
            Return mstrToolTipStyle
        End Get
        Set(ByVal value As String)
            mstrToolTipStyle = value
        End Set
    End Property

En la siguiente propiedad es donde asignamos el codigo HTML que vamos a utilizar para presentar información en el HtmlToolTip. Vemos como guardar en el ViewState el dato de esta propiedad para poder soportar postbacks de otros controles.

    ' esta propiedad es el texto Html de nuestro HtmlToolTip System.Web.UI.Design.HtmlControlDesigner
    <Bindable(True), Description("HTML que se mostrará en el HtmlToolTip")> _
    Property ToolTipHtmlText() As String
        Get
            Dim str As String
            If EnableViewState = True Then
                str = CType(ViewState("ToolTipHtmlText"), String)
            End If
            Return str
        End Get
        Set(ByVal value As String)
            If EnableViewState = True Then
                ViewState("ToolTipHtmlText") = value
            End If
            mstrToolTipTextoHtml = value
        End Set
    End Property
#End Region

En la siguiente sección de código se muestra la función donde ocurre la magia de poner y quitar el mensaje HtmlToolTip cuando el usuario pasa o quita el ratón sobre el control.

#Region "Funciones privadas"

    ' Funciones encargada de mostrar, mantener y desaparecer el HtmlToolTip
    Private Function ScriptFunctions() As String
        Dim strScript As New System.Text.StringBuilder
        Dim strSegundos As String

        strSegundos = CStr(CInt(mintSegundo) * 1000)
        With strScript
            .Append("<script type='text/jscript' language='jscript'> ")
            .Append(" var timeout = null; ")
            .Append(" var tipOffTimeout = null; ")
            .Append(" function TopicTipOn(anchor, id) { ")
            .Append("   var targetY = document.body.scrollTop + window.event.clientY + 18; ")
            .Append("   var targetX = document.body.scrollLeft + window.event.clientX + 12; ")
            .Append("       TopicTip.style.left = targetX; ")
            .Append("         TopicTip.style.top = targetY; ")
            .Append("         var tip =   document.getElementById(id); ")
            .Append("         TopicTip.innerHTML = tip.innerHTML; ")
            .Append("         TopicTip.style.display = 'block'; ")
            .Append("         if (tipOffTimeout != null) ")
            .Append("       window.clearTimeout(tipOffTimeout); ")
            .Append("         tipOffTimeout = window.setTimeout('TopicTipOff()', " & strSegundos & ", 'JScript'); }")
            .Append(" ")
            .Append(" function TopicTipOff() { ")
            .Append(" if (tipOffTimeout != null) ")
            .Append("    window.clearTimeout(tipOffTimeout);")
            .Append("    tipOffTimeout = null;                    ")
            .Append("   TopicTip.style.display = 'none'; }</script>")
        End With

        Return strScript.ToString
    End Function
#End Region

Bien y para finalizar el código a continuación se presenta el codigo encargado de registrar el javascript y el de extender la funcionalidad del control Hyperlink para asociar que funciones javascript se ejecutan en determinado evento.

 #Region "Overrides"
    ' verificamos si no existe el script ya registrado en caso que no exista
    ' registramos las funciones javascript que requerimos 
    Protected Overrides Sub OnPreRender(ByVal e As EventArgs)
        If Not MyBase.Page.IsClientScriptBlockRegistered("ToolTipScript") Then
            Page.RegisterClientScriptBlock("ToolTipScript", ScriptFunctions)
        End If

        ' verificamos si no existe el script TopicTip el cual es el encargado de
        ' actuar a nivel javascript con nuestro HtmlToolTip, en caso de que
        ' la propiedad ToolTipCss cuente con informacion asume que cuenta conarchivo
        ' Css y dentro de el el estilo visual del HtmlToolTip, en caso contrario
        ' utilizamos el estilo predeterminado

        If Not MyBase.Page.IsClientScriptBlockRegistered("TopicTip") Then
            If mstrCssHtmlToolTipStyle.Trim.Length > 0 Then
                Page.RegisterClientScriptBlock("TopicTip", "<div id='TopicTip' class='" & _

                                                            mstrCssHtmlToolTipStyle & "'></div>")
            Else
                Page.RegisterClientScriptBlock("TopicTip", "<div id='TopicTip' style='" & _

                                                            mstrToolTipStyle & "'></div>")
            End If
        End If
    End Sub

    ' extendemos el control HyperLink para especificar que eventos mandan llamar las
    ' funciones javascript apropiadas, ademas especificamos el texto HtmlToolTip que
    ' vamos a mostrar

    Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
        Dim strHtml As String
        strHtml = "<div id='" & MyBase.UniqueID & "' style='DISPLAY: none'>" & ToolTipHtmlText & "</div>"
        Attributes("onmouseover") = "TopicTipOn(this, '" & MyBase.UniqueID & "');"
        Attributes("onmouseout") = "TopicTipOff();"
        writer.Write(strHtml)
        MyBase.Render(writer)
    End Sub
#End Region
End Class

Por cierto el sub procedimiento Render envía el contenido del control a un objeto de tipo HtmlTextWriter el cual escribe una serie secuencial de caracteres HTML y texto en una página de formulario Web. La clase HtmlTextWriter provee de capacidades de formato que los controles de servidor ASP.NET utilizan cuando se renderiza contenido HTML en el cliente.

Una vez escrito el código compilemos el proyecto y generamos nueva versión del archivo ControlesWeb.dll ubicado en el fólder Bin del proyecto ControlesWeb

En el proyecto TestControlesWeb y agrega un nuevo formulario llamado WebForm5.aspx y expande el elemento References y seleccionamos ControlesWeb damos clic derecho y lo removemos. Ahora seleccionamos y damos doble clic en el WebForm5.aspx y en la ventana Toolbox presiona botón derecho del ratón y damos clic para seleccionar la opción Add and Remove Items. Buscamos y seleccionamos el archivo ControlesWeb.dll, damos clic en el titulo Namescape de la columna y se ordenara la lista de controles apareciendo al principio nuestros tres controles de servidor personalizados.

   

A continuación vamos a arrastrar un control de tipo HyperLinkHtmlToolTip sobre nuestro WebForm5.aspx , debido a que este nuevo control hereda del objeto  HyperLink cuenta con todas las propiedades originales del control  HyperLink más las nueva propiedades definidas anteriormente .

Vamos a establecer las siguientes propiedades del control HyperLinkHtmlToolTip1:

NOTA: Por el hecho de utilizar la propiedad ToolTipHtmlCss la cual asocia una clase css en donde ahi se define la presentación, por lo tanto, la propiedad ToolTipHtmlStyle no sera utilizada.

El valor de ToolTipHtmlText es:

<TABLE id=Table1 cellSpacing=0 cellPadding=3 width=300 border=0> <TR> <TD><IMG src=/TestControlesWeb/Images/membercenter60px.gif></TD> <TD class=BodyText>La serie de <B>controles de servidor personalizados ASP.NET</B> escritos por <b>Haaron Gonzalez</b> la encontraras en PanoramaBox</TD> </TR> </TABLE>

Como podras darte cuenta hice referencia a una archivo de imagen llamado membercenter60px.gif pero tu puedes utilizar el que quieras, tambien hago referencia al Class=BodyText el cual lo tengo en mi archivo style.css.

NOTA: No olvides hacer referencia al archivo Styles.css en el WebForm5.aspx, para hacer referencia solo selecciona Styles.css y arrastralo sobre el formulario WebForm5.aspx.

Ahora si tienes todo listo para ejecutar la aplicación y ver funcionando tu control personalizado HyperLinkHtmlToolTip1 verifica que cuando pasas el ratón sobre el control aparecerá un ToolTip mas rico en presentación.

 

Conclusión

En este artículo vimos como extender la funcionalidad del control System.Web.UI.WebControl.Hyperlink para agregar un poco de código javascript y poder mostrar un ToolTip basado en Html con capacidades ricas de presentación.


ir al índice