You are on page 1of 79

AJAX y ASP.

NET
Tema 10
Inadeco

AJAX

1.- Leer Tiempo del Cliente


Para obtener el tiempo del cliente necesitamos una funcin JavaScript.
// JScript File function clientTime() { var t = new Date(); return ( char2(t.getDate()) + "/" + char2(t.getMonth() + 1) + "/" + String(t.getYear()).substring(4,2) + " " + char2(t.getHours()) + ":" + char2(t.getMinutes()) + ":" + char2(t.getSeconds())); } function char2(v) { if ((v >= 0) && (v <= 9)) return "0" + v; else return v; }

AJAX y ASP.NET 2

Para programar un evento de temporizador del lado del cliente en una pgina web, JavaScript suministra un esquema sencillo, se activa un procedimiento invocando el mtodo setTimeout del objeto window, el cual usa como parmetros el nombre de la funcin que se va a llamar, y el tiempo en milisegundos de espera para hacer la llamada. Hacemos la primera llamada desde el evento de carga de la pgina, normalmente body onload o un Page Load. Para hacer el temporizador continuo, la funcin que se invoca en setTimeout debe llamar nuevamente a setTimeout. Por ltimo si queremos mostrar el resultado en la pagina, desde unas lneas escribimos en un control del lado del cliente. En el siguiente ejemplo el tiempo del cliente se muestra en una caja de texto de html de nombre txtClientTime. Finalmente el cdigo de la pgina es el siguiente:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="tiempodelcliente._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Tiempo del Cliente</title> <script type="text/javascript" src="ClientTime.js"></script> <script type="text/javascript"> // activando un "Timer" function timerEvent() { showClientTime(); // hace continuo el Timer window.setTimeout("timerEvent()", 1000); } function showClientTime() { t = clientTime(); var r = document.getElementById("txtClientTime"); r.value = t; } </script>

</head> <body onload="window.setTimeout('timerEvent()',1500);"> <form id="form1" runat="server"> <div> <span>Tu Hora: </span> <input id="txtClientTime" type="text" style="width: 200px" /> </div> </form> </body> </html>

AJAX y ASP.NET 3

Siempre que se quieran datos del cliente es necesario recurrir a cdigo del lado del cliente.

2.- Leer tiempo del Servidor con PostBack


Leer el tiempo del servidor en un postback no requiere mucha discusin. Solo necesitamos un control asp con postback. En el cdigo del lado del servidor leemos el retorno de la funcin DateTime.Now(). Si queremos mostrarla en un control la asignamos directamente. Ejemplo, usamos un botn btnServerTime y una caja de texto txtServerTime:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="tiempodelservidorconpostback._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Tiempo del servidor con postback</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Button ID="btnServerTime" runat="server" onclick="btnServerTime_Click" Text="Dame la hora" /> <asp:TextBox ID="txtHora" runat="server"></asp:TextBox> </div> </form> </body> </html>

3.- Instalacin de AJAX con ASP.NET


3.1.- Requisitos de Sistema
Sistemas Operativos Windows 2003 Server Windows XP Windows Vista Otras Versiones que soporten .NET Framework 2.0

Software Requerido .NET Framework 2.0 o 3.0 IE 5.0 o posterior Software Opcional Visual Studio 2005 Visual Web Developer Express Edition

AJAX y ASP.NET 4

3.2.- Pasos de la Instalacin


1. Derechos de Administrador de la mquina 2. Desinstalar versiones anteriores de ASP.NET AJAX 3. Descargar ASPAJAXExtSetup.msi http://www.asp.net/ajax/default.aspx 4. Instalar ASPAJAXExtSetup.msi

Una vez instalado, ya contaremos con novedades en el Visual Studio 2005

AJAX y ASP.NET 5

5. Descargar ASP.NET AJAX Control Toolkit

AJAX y ASP.NET 6

6. Instalar ASP.NET AJAX Control Toolkit

3.3.-Introduccin a ASP.NET AJAX


Componentes relacionados con las posibilidades de AJAX en ASP.NET: Microsoft AJAX Library es un conjunto de archivos de JavaScript que hacen fcil la programacin de JavaScript del lado del cliente. Incluye soporte para clases, espacios de nombre, eventos, tipos de datos, etc. Tambin soporta manejo de errores, depuracin, y globalizacin. La librera combina JavaScript y DHTML. La librera es usada por ASP.NET y los Ajax Control Toolkit. Sin embargo, tambin podemos aprovechar la librera para ampliar nuestros propios controles con comportamientos de JavaScript. Controles de Servidor ASP.NET AJAX. Son controles de servidor que podemos colocar en las pginas ASP.NET, para realizar actualizaciones parciales de pgina, comunicaciones con un proceso del servidor para indicar el progreso, y actualizar peridicamente porciones de pgina. AJAX CONTROL TOOLKIT. Es un conjunto de controles que muestran el poder de AJAX. Estos controles pueden ser usados en nuestras pginas web. Cajas con mascaras, sliders, filtros, pop-up, etc. Es una extensin para Visual Studio y ASP.NET. http://www.asp.net/ajax Soporte Servicios Web del lado del cliente. Proporciona soporte para llamadas a servicios web de manera asncrona desde el cliente usando JSON y XML

3.4.- Usos y Beneficios de ASP.NET AJAX


Las caractersticas de ASP.NET AJAX proveen una experiencia de usuario ms rica que la de las aplicaciones web estndar:

Actualizaciones parciales de pgina. Permite definir un rea que debera actualizarse y realizar Postback. Procesar del lado del cliente. Proporciona interactividad, informacin inmediata y capacidad de respuesta a los usuarios. UI como aplicacin de escritorio. Provee a los usuarios cajas de dialogo modal, indicadores de progreso, mscaras, tooltips, etc. Indicadores de Progreso. Permite mostrar el progreso de un proceso del lado del servidor y actualizacin continua en el usuario. Mejora del rendimiento. Podemos incrementar el rendimiento procesando partes de una pgina en el cliente. Llamadas desde el cliente a un servicio web. Permite llamadas al servidor directamente desde script del cliente

AJAX y ASP.NET 7

4.- Leer Tiempo del Servidor usando AJAX ASP.NET


Para resolver el problema bastan tres controles del servidor de Ajax ASP.NET : ScriptManager, Update Panel y Timer.
ScriptManager. Es requerido en toda pgina potenciada con AJAX. UpdatePanel. Es un contenedor especializado en manejar el refresco parcial de la pgina y evitar el efecto postback. El panel se actualiza en accin a un disparador, Trigger que no es ms que otro elemento el cual tiene codificado la accin, ya sea un evento o el cambio de una propiedad de un control de la pgina que har que se actualice el contenido del panel de AJAX. TimerControl. Es un control de AJAX que suministra un objeto temporizador entre la pgina web y el servidor. Anteriormente, un temporizador del lado del servidor en paginas ASP.NET era una cuestin inverosmil o demasiado laboriosa.

%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="tiemposervidorAJAX._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Pgina sin ttulo</title> </head> <body> <form id="form1" runat="server"> <h2> Tiempo del Servidor con Atlas</h2> <hr /> <div> <asp:ScriptManager runat="server" id="sm" enablepartialrendering="true" /> <asp:Timer runat="server" id="tmrServerTime" interval="1500" ontick="tmrServerTime_Tick" /> <asp:UpdatePanel id="up1" runat="server"> <Triggers> <asp:AsyncPostBackTrigger ControlID="tmrServerTime" EventName="Tick" /> </Triggers> <ContentTemplate> <asp:TextBox ID="txtServerTime" runat="server" Width="220px" />

</ContentTemplate> </asp:UpdatePanel> </div> <div> <input id="txtClientTime" type="text" style="width: 220px" runat="server" /> </div> <hr /> </form> </body> </html>

AJAX y ASP.NET 8

La respuesta del evento temporizador se recibe en el servidor. Sorprendentemente, se puede asumir el temporizador casi de la misma forma que en una aplicacin Windows.
protected void tmrServerTime_Tick(object sender, EventArgs e) { this.txtServerTime.Text = DateTime.Now.ToString("dd/mm/yy hh:mm:ss"); }

5.- Controles de Servidor de AJAX

6.- Control ScriptManager


El control ScriptManager administra el script de cliente para las pginas web habilitadas para ASP.NET AJAX. De forma predeterminada, el control ScriptManager registra el script para Microsoft AJAX Library con la pgina. Esto permite a los script de cliente usar las extensiones del sistema tipo y admitir algunas caractersticas, como la representacin parcial de pginas y las llamadas de servicio web. Control principal de la infraestructura de servidor de ASP.NET AJAX. Ninguna funcionalidad de AJAX puede ser habilitada en las pginas ASPNET AJAX sin que se haga referencia a este control.

Debe usar un control ScriptManager en una pgina para habilitar las siguientes caractersticas AJAX de ASP.NET:

AJAX y ASP.NET 9

Funcionalidad de script de cliente de Microsoft AJAX Library y todos los scripts personalizados que desee enviar al explorador. La representacin parcial de pginas, que permite actualizar partes de la pgina de forma independiente sin que exista ninguna devolucin de datos. Los controles UpdatePanel, UpdateProgress y Timer de ASP.NET requieren un control ScriptManager para admitir la representacin parcial de pginas. Las clases de proxy JavaScript para los servicios web, que permiten usar scripts de cliente para tener acceso a servicios web y mtodos marcados especialmente en las pginas ASP.NET. Para ello, expone los servicios web y los mtodos de pgina como objetos con establecimiento inflexible de tipos. Clases JavaScript para obtener acceso a los servicios de aplicacin de autenticacin, perfiles y funciones de ASP.NET.

<asp:ScriptManager runat="server" id="sm" enablepartialrendering="true" />

7.- ScriptManagerProxy
El control ScriptManagerProxy permite que los componentes anidados, como pginas de contenido y controles de usuario, agreguen a las pginas referencias a scripts y servicios cuando ya se ha definido un control ScriptManager en un elemento primario. Una pgina web slo puede contener un control ScriptManager, bien de forma directa en la propia pgina, o de forma indirecta en un componente anidado o primario. El control ScriptManagerProxy permite agregar scripts y servicios a pginas de contenido y controles de usuario donde la pgina maestra o la pgina host ya contienen un control ScriptManager. Cuando se usa el control ScriptManagerProxy, puede agregar las colecciones de scripts y servicios definidas por el control ScriptManager. Si no desea incluir scripts y servicios especficos a cada pgina que incluya un control ScriptManager determinado, qutelos del control ScriptManager y agrguelos a pginas individuales mediante el control ScriptManagerProxy.

8.- El Control UpdatePanel


Los controles de ASP.NET UpdatePanel permiten generar aplicaciones web enriquecidas y centradas en el cliente. Mediante el uso de los controles UpdatePanel, se pueden actualizar partes seleccionadas de la pgina en lugar de actualizar toda la pgina con una devolucin de datos. Esto se conoce como actualizacin parcial de la pgina. Una pgina web ASP.NET que

contiene un control ScriptManager y uno o varios controles UpdatePanel puede participar automticamente en las actualizaciones parciales de la pgina, sin un script de cliente personalizado.

AJAX y ASP.NET 10

El control UpdatePanel es un control de servidor que ayuda a desarrollar pginas web con un comportamiento de cliente complejo que hace que una pgina web parezca ms interactiva al usuario final. Normalmente, escribir cdigo que se coordine entre el servidor y el cliente para actualizar slo las partes especificadas de una pgina web requiere un conocimiento detallado de ECMAScript (JavaScript). Sin embargo, mediante el uso del control UpdatePanel, puede hacer que una pgina web participe en las actualizaciones parciales de pgina sin necesidad de escribir ningn script de cliente. Si lo desea, puede agregar el script de cliente personalizado para mejorar la experiencia del usuario cliente. Cuando se usa un control UpdatePanel, el comportamiento de la pgina es independiente del explorador y puede reducir la cantidad de datos que se transfieren entre el cliente y el servidor. Los controles UpdatePanel trabajan especificando las regiones de una pgina que se pueden actualizar sin actualizar la pgina entera. Este proceso se coordina mediante el control de servidor ScriptManager y la clase de cliente PageRequestManager. Cuando las actualizaciones parciales de la pgina estn habilitadas, los controles pueden enviar al servidor de forma asincrnica. Una devolucin de datos asincrnica se comporta como una devolucin de datos normal en cuanto que la pgina de servidor resultante ejecuta la pgina completa y controla el ciclo de vida. Sin embargo, con una devolucin de datos asincrnica, las actualizaciones de la

pgina se limitan a las regiones de la pgina que estn incluidas en los controles UpdatePanel y que estn marcadas para actualizarse. El servidor enva el marcado HTML al explorador slo para los elementos implicados. Habilitar actualizaciones parciales de pgina El control UpdatePanel requiere un control ScriptManager en la pgina web. De forma predeterminada, las actualizaciones parciales de la pgina estn habilitadas porque el valor predeterminado de la propiedad EnablePartialRendering del control ScriptManager es True. Especificar el contenido del control UpdatePanel Puede agregar contenido a un control UpdatePanel colocndolo en el panel de la vista Diseo. Por ejemplo, puede arrastrar otros controles ASP.NET y HTML al panel, y situar el cursor en el panel y escribir directamente en l. Cuando agrega contenido a un control UpdatePanel en la vista Diseo, automticamente se agregan las etiquetas requeridas <ContentTemplate></ContentTemplate> alrededor del contenido. Si agrega contenido a un control UpdatePanel en la vista Cdigo en lugar de la vista Diseo, debe agregar las etiquetas <ContentTemplate></ContentTemplate> manualmente si no existen ya; de lo contrario, el contenido no se representar en el control UpdatePanel. Cuando se representa por primera vez una pgina que contiene uno o varios controles UpdatePanel, se representa todo el contenido de los controles UpdatePanel y se enva al explorador. En las devoluciones de datos asincrnicas posteriores, el contenido de los controles UpdatePanel individuales podra actualizarse. Las actualizaciones dependen de las opciones de configuracin del panel, de qu elemento produjo la devolucin de datos y del cdigo especfico de cada panel. Especificar los desencadenadores UpdatePanel De forma predeterminada, cualquier control de devolucin de datos dentro de un control UpdatePanel produce una devolucin de datos asincrnica y actualiza el contenido del panel. Sin embargo, tambin puede configurar otros controles de la pgina para actualizar un control UpdatePanel. Para ello, defina un desencadenador para el control UpdatePanel. Un desencadenador es un enlace que especifica qu evento y qu control de devolucin de datos provocan la actualizacin de un panel. Cuando se provoca el evento especificado del control desencadenador (por ejemplo, un evento Click de un botn), se actualiza el panel de actualizacin. Puede crear desencadenadores de un control UpdatePanel mediante el cuadro de dilogo Editor de la coleccin UpdatePanelTrigger, que se visualiza desde la propiedad Triggers (Desencadenadores) en el panel de tareas Propiedades de etiqueta. Los eventos de control de los desencadenadores son opcionales. Si no se especifica un evento, el evento desencadenador es el evento predeterminado del control. Por ejemplo, para el control Button, el evento predeterminado es el evento Click. Cmo se actualizan los controles UpdatePanel

AJAX y ASP.NET 11

En la lista siguiente se describen los valores de las propiedades del control UpdatePanel que determinan cundo se actualiza el contenido de un panel durante la representacin parcial de la pgina:

AJAX y ASP.NET 12

Si la propiedad UpdateMode se establece en Always, el contenido de control UpdatePanel se actualiza en todas las devoluciones de datos que se originen en cualquier lugar de la pgina. Esto incluye las devoluciones de datos asincrnicas de los controles que estn dentro de otros controles UpdatePanel y las devoluciones de datos de los controles que no estn dentro de los controles UpdatePanel. Si la propiedad UpdateMode se establece en Conditional, el contenido del control UpdatePanel se actualiza cuando se da una de las siguientes condiciones:

Cuando un desencadenador produce la devolucin de datos para ese control UpdatePanel. Cuando se llama explcitamente al mtodo Update del control UpdatePanel. Cuando se anida el control UpdatePanel dentro de otro control UpdatePanel y se actualiza el panel primario. Cuando la propiedad ChildrenAsTriggers se establece en True y cualquier control secundario del control UpdatePanel provoca una devolucin de datos. Los controles secundarios de los controles UpdatePanel anidados no provocan actualizaciones del control UpdatePanel externo a menos que se definan explcitamente como desencadenadores para el panel primario.

Si la propiedad ChildrenAsTriggers se establece en False y la propiedad UpdateMode se establece en Always, se inicia una excepcin. La propiedad ChildrenAsTriggers est diseada para utilizarse slo cuando la propiedad UpdateMode se establezca en Conditional. Usar los controles UpdatePanel anidados Los controles UpdatePanel se pueden anidar. Si se actualiza el panel primario, todos los paneles anidados tambin se actualizarn. Si se actualiza un panel secundarios, se actualiza slo el panel secundario.

Configurar la actualizacin condicional


Por defecto, los paneles actualizables en una pgina estn sincronizados y se actualizan al mismo tiempo. Para hacer que cada panel se actualice independientemente de los otros, podemos cambiar el valor de la propiedad UpdateMode. EL valor por defecto es Always, lo que significa que el contenido del panel se actualiza en cada postback que se origina desde cualquier lugar en la pgina, desde dentro o fuera de la regin actualizable. AL cambiar el valor de la propiedad UpdateMode a Conditional, instruimos el panel actualizable para actualizar su contenido slo si se ordena explcitamente que se actualice.

Esto incluye llamar al mtodo Update, interceptar un postback desde un control hijo o cualquiera de los eventos declarados como desencadenadores.

AJAX y ASP.NET 13

Normalmente, cualquier control definido dentro de un control UpdatePanel acta como un desencadenador implcito para el panel. Podemos evitar que todos los controles hijo pasen a ser desencadenadores configurando el valor ChildrenAsTriggers como false. En este caso, un botn dentro del panel actualizable originara, al hacer clic sobre l, un postback completo normal Si slo queremos que unos cuantos controles dentro de UpdatePanel acten como desencadenadores, podemos definirlos como desencadenadores de un UpdatePanel concreto o podemos utilizar el mtodo RegisterAsyncPostBackControl de la clase ScriptManager. Este mtodo nos permite registrar controles para realizar un postback asncrono en vez de sincrono. ScriptManager1.RegisterAsyncPOstBackControl(Button1); EL objeto control que pasamos como un argumento ser un control no incluido en ningn panel actualizable y no es enumerable como un desencadenador. Los efectos en el postback que se originan desde el control son diferentes dependiendo del nmero de controles UpdatePanel de la pgina. Si hay slo un UpdatePanel en la pgina, el administrador de script puede deducir fcilmente cul actualizar Cuando existen paneles mltiples, para provocar la actualizacin tenemos que invocar explcitamente el mtodo Update en el panel que queremos actualizar. UpdatePanel1.Update(); Todos los controles localizados dentro del control UpdatePanel son pasados automticamente como un argumento al mtodo RegisterAsyncPostBackControl cuando ChildrenAsTriggers est activada como true.

Uso de triggers
Podemos asociar un control UpdatePanel con una enumeracin de eventos del lado del servidor. Si un evento registrado es desencadenado por un postback el panel se actualiza. Los desencadenadores pueden definirse de manera declarativa o mediante programacin. Aadimos un evento desencadenador de forma declarativa mediante la seccin <Triggers> del control UpdatePanel. Necesitamos especificar dos informaciones para cada desencadenador: la ID de control que se va a supervisar y el nombre del evento que se va a capturar. Resulta impresindible subrayar que el componente AsyncPostBackTrigger puede modificar tan solo eventos del lado del servidor. Por lo tanto, esto implica que el control debe tener AutoPostBack a true

En el ejemplo siguiente se muestra un marcado que define un control ScriptManager y un control UpdatePanel en una pgina. El control UpdatePanel contiene un control Button que actualiza el contenido del panel al hacer clic en l. De forma predeterminada, la propiedad ChildrenAsTriggers es true. Por consiguiente, el control Button acta como un control de devolucin de datos asincrnica.
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected void Button_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(3000); } </script> <html> <head id="Head1" runat="server"> <title>UpdateProgress Example</title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager" runat="server" /> <asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server"> <ContentTemplate> <fieldset> <legend>UpdatePanel content</legend> <!-- Other content in the panel. --> <%=DateTime.Now.ToString() %> <br /> <asp:Button ID="Button1" Text="Refresh Panel" runat="server" /> </fieldset> </ContentTemplate> </asp:UpdatePanel> </form> </body> </html>

AJAX y ASP.NET 14

En el ejemplo siguiente se muestra cmo especificar un desencadenador para un control UpdatePanel.


<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected void Button_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(3000); } </script> <html>

<head id="Head1" runat="server"> <title>UpdateProgress Example</title> </head> <body> <form id="form1" runat="server"> <asp:Button ID="Button1" Text="Refresh Panel" runat="server" /> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server"> <Triggers> <asp:AsyncPostBackTrigger ControlID="Button1" /> </Triggers> <ContentTemplate> <fieldset> <legend>UpdatePanel content</legend> <%=DateTime.Now.ToString() %> </fieldset> </ContentTemplate> </asp:UpdatePanel> </form> </body> </html>

AJAX y ASP.NET 15

En el ejemplo siguiente se muestra el marcado para un control ScriptManager en la pgina maestra y un control UpdatePanel en una pgina de contenido. En este ejemplo, en la pgina maestra hay definida una propiedad denominada LastUpdate y se hace referencia a ella desde el control UpdatePanel.
<%@ Master Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> public DateTime LastUpdate { get { return (DateTime)(ViewState["LastUpdate"] ?? DateTime.Now); } set { ViewState["LastUpdate"] = value; } }

protected void MasterButton2_Click(object sender, EventArgs e) { LastUpdate = DateTime.Now; ((UpdatePanel)ContentPlaceHolder1.FindControl("UpdatePanel1")).Update( ); } protected void Page_Load(object sender, EventArgs e) {

ScriptManager1.RegisterAsyncPostBackControl(Button2); } </script>

AJAX y ASP.NET 16

<html > <head id="Head1" runat="server"> <title>ScriptManager in Master Page Example</title> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <asp:Panel ID="MasterPanel1" runat="server" GroupingText="Master Page"> <asp:Button ID="Button1" runat="server" Text="Full Page Refresh" /> <asp:Button ID="Button2" runat="server" Text="Refresh Panel" OnClick="MasterButton2_Click" /> </asp:Panel> <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server"> </asp:ContentPlaceHolder> </div> </form> </body> </html>

<%@ Page Language="C#" MasterPageFile="MasterCS.master" Title="ScriptManager in Content Page" %> <%@ MasterType VirtualPath="MasterCS.master" %> <script runat="server"> protected void Button3_Click(object sender, EventArgs e) { Master.LastUpdate = DateTime.Now; } </script> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server"> <asp:Panel ID="Panel2" GroupingText="ContentPage" runat="server" > <asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server"> <ContentTemplate> <p> Last updated: <strong> <%= Master.LastUpdate.ToString() %> </strong> </p> <asp:Button ID="Button3" Text="Refresh Panel" OnClick="Button3_Click"

runat="server" </ContentTemplate> </asp:UpdatePanel> </asp:Panel> </asp:Content>

/>

AJAX y ASP.NET 17

El ejemplo siguiente muestra el marcado que define un control UpdatePanel dentro de otro control UpdatePanel. Un botn del panel primario desencadena una actualizacin del contenido tanto en el panel primario como secundario. El botn del panel secundario desencadena una actualizacin slo del panel secundario.
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> </script> <html > <head id="Head1" runat="server"> <title>UpdatePanelUpdateMode Example</title> <style type="text/css"> div.NestedPanel { position: relative; margin: 2% 5% 2% 5%; } </style> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager" runat="server" /> <asp:UpdatePanel ID="OuterPanel" UpdateMode="Conditional" runat="server"> <ContentTemplate> <div> <fieldset> <legend>Outer Panel </legend> <br /> <asp:Button ID="OPButton1" Text="Outer Panel Button" runat="server" /> <br /> Last updated on <%= DateTime.Now.ToString() %> <br /> <br /> <asp:UpdatePanel ID="NestedPanel1" UpdateMode="Conditional" runat="server"> <ContentTemplate> <div class="NestedPanel"> <fieldset> <legend>Nested Panel 1</legend> <br /> Last updated on <%= DateTime.Now.ToString() %> <br /> <asp:Button ID="NPButton1"

Text="Nested Panel 1 Button" </fieldset> </div> </ContentTemplate> </asp:UpdatePanel> </fieldset> </div> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html> runat="server" />

AJAX y ASP.NET 18

En el ejemplo siguiente se muestra un control UpdatePanel anidado con un control GridView. El control GridView est dentro de un control UpdatePanel, y cada fila de GridView contiene un control GridView anidado en otro control UpdatePanel.
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <head id="Head1" runat="server"> <title>Browse Departments</title> <script runat="server"> protected void DepartmentsGridView_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { SqlDataSource s = (SqlDataSource)e.Row.FindControl("EmployeesDataSource"); System.Data.DataRowView r = (System.Data.DataRowView)e.Row.DataItem; s.SelectParameters["DepartmentID"].DefaultValue = r["DepartmentID"].ToString(); } } </script> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager runat="server" ID="ScriptManager1" EnablePartialRendering="true" /> <asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:GridView ID="DepartmentsGridView" runat="server" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" CellPadding="4" DataSourceID="DepartmentDataSource" ForeColor="#333333" GridLines="None" PageSize="3" OnRowDataBound="DepartmentsGridView_RowDataBound"> <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" /> <Columns> <asp:BoundField DataField="GroupName" HeaderText="Division" SortExpression="GroupName" > <ItemStyle Width="200px" /> </asp:BoundField>

<asp:BoundField DataField="Name" HeaderText="Department Name" SortExpression="Name" > <ItemStyle Width="160px" /> </asp:BoundField> <asp:TemplateField HeaderText="Employees"> <ItemTemplate> <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:GridView ID="EmployeesGridView" runat="server" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" BackColor="White" BorderColor="#999999" BorderStyle="None" BorderWidth="1px" CellPadding="3" DataSourceID="EmployeesDataSource" GridLines="Vertical" PageSize="4"> <FooterStyle BackColor="#CCCCCC" ForeColor="Black" /> <Columns> <asp:BoundField DataField="FirstName" HeaderText="First Name" SortExpression="FirstName" > <ItemStyle Width="80px" /> </asp:BoundField> <asp:BoundField DataField="LastName" HeaderText="Last Name" SortExpression="LastName" > <ItemStyle Width="160px" /> </asp:BoundField> </Columns> <RowStyle BackColor="#EEEEEE" ForeColor="Black" /> <SelectedRowStyle BackColor="#008A8C" Font-Bold="True" ForeColor="White" /> <PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" /> <HeaderStyle BackColor="#000084" FontBold="True" ForeColor="White" /> <AlternatingRowStyle BackColor="Gainsboro" /> </asp:GridView> <asp:Label runat="server" ID="InnerTimeLabel"><%=DateTime.Now %></asp:Label> <asp:SqlDataSource ID="EmployeesDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>" SelectCommand="SELECT HumanResources.EmployeeDepartmentHistory.DepartmentID, HumanResources.vEmployee.EmployeeID, HumanResources.vEmployee.FirstName, HumanResources.vEmployee.LastName FROM HumanResources.EmployeeDepartmentHistory INNER JOIN HumanResources.vEmployee ON HumanResources.EmployeeDepartmentHistory.EmployeeID = HumanResources.vEmployee.EmployeeID WHERE HumanResources.EmployeeDepartmentHistory.DepartmentID = @DepartmentID ORDER BY HumanResources.vEmployee.LastName ASC, HumanResources.vEmployee.FirstName ASC"> <SelectParameters> <asp:Parameter Name="DepartmentID" DefaultValue="0" Type="int32" /> </SelectParameters>

AJAX y ASP.NET 19

</asp:SqlDataSource> </ContentTemplate> </asp:UpdatePanel> </ItemTemplate> <ItemStyle Height="170px" Width="260px" /> </asp:TemplateField> </Columns> <RowStyle BackColor="#F7F6F3" ForeColor="#333333" VerticalAlign="Top" /> <EditRowStyle BackColor="#999999" /> <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" /> <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" /> <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" HorizontalAlign="Left" /> <AlternatingRowStyle BackColor="White" ForeColor="#284775" VerticalAlign="Top" /> </asp:GridView> <asp:Label runat="server" ID="OuterTimeLabel"><%=DateTime.Now %></asp:Label> </ContentTemplate> </asp:UpdatePanel> &nbsp; <asp:SqlDataSource ID="DepartmentDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>" SelectCommand="SELECT DepartmentID, Name, GroupName FROM HumanResources.Department ORDER BY Name"> </asp:SqlDataSource> </div> </form> </body> </html>

AJAX y ASP.NET 20

En el ejemplo siguiente se muestra cmo actualizar un control UpdatePanel mediante programacin. En este ejemplo, una pgina registra un control como desencadenador mediante una llamada al mtodo RegisterAsyncPostBackControl. El cdigo actualiza el control UpdatePanel mediante programacin mediante una llamada al mtodo Update.
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected SortedList AnsweredQuestions { get { return (SortedList)(ViewState["AnsweredQuestions"] ?? new SortedList()); } set { ViewState["AnsweredQuestions"] = value; } } protected void Page_Load() { ScriptManager1.RegisterAsyncPostBackControl(SurveyDataList); } protected void ChoicesRadioButtonList_SelectedIndexChanged(object sender, EventArgs e) { SortedList answers = this.AnsweredQuestions; RadioButtonList r = (RadioButtonList)sender; answers[r.ToolTip] = r.SelectedValue;

this.AnsweredQuestions = answers; ResultsList.DataSource = this.AnsweredQuestions; ResultsList.DataBind();

AJAX y ASP.NET 21

if (this.AnsweredQuestions.Count == SurveyDataList.Items.Count) SubmitButton.Visible = true; UpdatePanel1.Update(); } protected void SubmitButton_Click(object sender, EventArgs e) { // Submit responses. } </script> <html > <head id="Head1" runat="server"> <title>Registering Controls as Async Postback Controls</title> <style type="text/css"> .AnswerFloatPanelStyle { background-color: bisque; position: absolute; right: 10px; height: 130px; width: 150px; border-right: silver thin solid; border-top: silver thin solid; border-left: silver thin solid; border-bottom: silver thin solid; } </style> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <div id="AnswerFloatPanel" class="AnswerFloatPanelStyle" runat="server"> <asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server"> <ContentTemplate> Completed Questions: <asp:DataList ID="ResultsList" runat="server"> <ItemTemplate> <asp:Label ID="ResultQuestion" runat="server" Text='<%# Eval("Key") %>' /> :: <asp:Label ID="ResultAnswer" runat="server" Text='<%# Eval("Value") %>' /> </ItemTemplate> </asp:DataList> <p style="text-align: right"> <asp:Button ID="SubmitButton" Text="Submit" runat="server" Visible="false" OnClick="SubmitButton_Click" /> </p> <asp:Label ID="Message" runat="Server" /> </ContentTemplate> </asp:UpdatePanel> </div> <asp:XmlDataSource ID="SurveyDataSource" runat="server" XPath="/Questions/Question" DataFile="~/App_Data/SurveyQuestions.xml"/> <asp:DataList ID="SurveyDataList" DataSourceID="SurveyDataSource"

runat="server">

AJAX y ASP.NET 22

<ItemTemplate> <table cellpadding="2" cellspacing="2"> <tr> <td valign="top"> <asp:Label id="QuestionLabel" Text='<%# XPath("@Title")%>' runat="server" /> </td> </tr> <tr><td> <asp:RadioButtonList ID="ChoicesRadioButtonList" runat="server" DataSource='<%#XPathSelect("Choices/Choice") %>' DataTextField="InnerText" DataValueField="InnerText" AutoPostBack="True" ToolTip='<%# "Question" + XPath("@ID") %>' OnSelectedIndexChanged="ChoicesRadioButtonList_SelectedIndexChanged"/> </td></tr> </table> <hr /> </ItemTemplate> </asp:DataList> </div> </form> </body> </html>

<?xml version="1.0" encoding="UTF-8"?> <!--Sample XML file, you should put it in App_Data folder --> <Questions> <Question Title="Favorite color?" ID="0"> <Choices> <Choice>Red</Choice> <Choice>Green</Choice> <Choice>Blue</Choice> </Choices> </Question> <Question Title="Favorite day or the week?" ID="1"> <Choices> <Choice>Monday</Choice> <Choice>Tuesday</Choice> <Choice>Wednesday</Choice> </Choices> </Question> <Question Title="Favorite activities?" ID="2"> <Choices> <Choice>Gardening</Choice>

<Choice>Skiing</Choice> <Choice>Walking</Choice> </Choices> </Question> </Questions>

AJAX y ASP.NET 23

7.-El control UpdateProgress


El control UpdateProgress proporciona informacin de estado acerca de las actualizaciones parciales de pginas en los controles UpdatePanel. Puede personalizar el contenido predeterminado y el diseo del control UpdateProgress. Para evitar que se produzcan intermitencias cuando una actualizacin parcial de pginas es muy rpida, puede especificar un retraso antes de que se muestre el control UpdateProgress. El control UpdateProgress ayuda a disear una interfaz de usuario ms intuitiva cuando una pgina web contiene uno o ms controles UpdatePanel de representacin parcial de pginas. Si una actualizacin parcial de pginas es lenta, puede usar el control UpdateProgress para proporcionar comentarios visuales acerca del estado de la actualizacin. Puede colocar varios controles UpdateProgress en una pgina, cada uno de ellos asociado con un control UpdatePanel distinto. Como alternativa, puede usar un control UpdateProgress y asociarlo con todos los controles UpdatePanel de la pgina. El control UpdateProgress representa un elemento <div> que se muestra u oculta en funcin de que un control UpdatePanel asociado haya provocado o no una devolucin asincrnica. El control UpdateProgress no aparece para la representacin de la pgina inicial y las devoluciones sincrnicas. Asociar un control UpdateProgress con un UpdatePanel Para asociar un control UpdateProgress con un control UpdatePanel, debe establecer la propiedad AssociatedUpdatePanelID del control UpdateProgress. Cuando se origina un evento de devolucin desde un control UpdatePanel, se muestran los controles UpdateProgress asociados. Si no se asocia el control UpdateProgress con un control UpdatePanel especfico, el control UpdateProgress muestra el progreso de las devoluciones asincrnicas. Si la propiedad ChildrenAsTriggers de un control UpdatePanel se establece en false y se origina una devolucin asincrnica desde dicho control UpdatePanel, se mostrarn todos los controles UpdateProgress asociados. Crear contenido para el UpdateProgress Para especificar el mensaje que muestra un control UpdateProgress, coloque el contenido que desee en el panel de la vista Diseo. Por ejemplo, puede arrastrar otros controles ASP.NET y HTML al panel y, a continuacin, colocar el cursor en el panel y escribir directamente en l. Al agregar un mensaje a un control UpdateProgress en la vista Diseo, se agregan

automticamente las etiquetas <ProgressTemplate> necesarias alrededor del contenido. Si agrega contenido a un control UpdateProgress en la vista Cdigo en lugar de hacerlo en la vista Diseo, debe agregar manualmente las etiquetas <ProgressTemplate></ProgressTemplate> si an no existen; de lo contrario, el mensaje no se representar. Especificar el diseo de contenido Si la propiedad DynamicLayout es true, el control UpdateProgress no ocupa espacio inicialmente en la presentacin de la pgina. En su lugar, la pgina cambia dinmicamente para mostrar el contenido del control UpdateProgress cuando es necesario. Para admitir la presentacin dinmica, el control se representa como un elemento <div> cuya propiedad de estilo de presentacin se ha establecido inicialmente en none. Si la propiedad DynamicLayout es false, el control UpdateProgress ocupa espacio en la presentacin de la pgina, aunque no sea visible. En tal caso, el elemento <div> del control tiene la propiedad de estilo de presentacin establecida en block y la visibilidad establecida inicialmente en hidden. Colocar controles UpdateProgress en la pgina Los controles UpdateProgress pueden colocarse dentro o fuera de los controles UpdatePanel. Un control UpdateProgress aparece cuando el control UpdatePanel con el que est asociado se actualiza como resultado de una devolucin asincrnica. Esto se cumple aunque el control UpdateProgress se encuentre dentro de otro control UpdatePanel. Si un control UpdatePanel se encuentra dentro de otro panel de actualizacin, una devolucin originada dentro del panel secundario hace que se muestren los controles UpdateProgress asociados con el panel secundario. Tambin se muestran los controles UpdateProgress asociados con el panel primario. Si se origina una devolucin desde un control secundario inmediato del panel primario, slo se muestran los controles UpdateProgress asociados con el panel primario. Esto sigue la lgica del desencadenamiento de devoluciones.
<asp:UpdateProgress ID="UpdateProgress1" runat="server"> <ProgressTemplate> An update is in progress... </ProgressTemplate> </asp:UpdateProgress>

AJAX y ASP.NET 24

En el ejemplo siguiente se muestra un control UpdateProgress que muestra el estado de actualizacin de dos controles UpdatePanel.
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected void Button_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(3000); } </script>

AJAX y ASP.NET
<html > <head id="Head1" runat="server"> <title>UpdateProgress Example</title> <style type="text/css"> #UpdatePanel1, #UpdatePanel2, #UpdateProgress1 { border-right: gray 1px solid; border-top: gray 1px solid; border-left: gray 1px solid; border-bottom: gray 1px solid; } #UpdatePanel1, #UpdatePanel2 { width:200px; height:200px; position: relative; float: left; margin-left: 10px; margin-top: 10px; } #UpdateProgress1 { width: 400px; background-color: #FFC080; bottom: 0%; left: 0px; position: absolute; } </style> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server"> <ContentTemplate> <%=DateTime.Now.ToString() %> <br /> <asp:Button ID="Button1" runat="server" Text="Refresh Panel" OnClick="Button_Click" /> </ContentTemplate> </asp:UpdatePanel> <asp:UpdatePanel ID="UpdatePanel2" UpdateMode="Conditional" runat="server"> <ContentTemplate> <%=DateTime.Now.ToString() %> <br /> <asp:Button ID="Button2" runat="server" Text="Refresh Panel" OnClick="Button_Click"/> </ContentTemplate> </asp:UpdatePanel> <asp:UpdateProgress ID="UpdateProgress1" runat="server"> <ProgressTemplate> Update in progress... </ProgressTemplate> </asp:UpdateProgress> </div> </form> </body> </html>

25

En el ejemplo siguiente se muestran dos controles UpdateProgress. Cada control muestra el estado de actualizacin de un control UpdatePanel asociado.
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected void Button_Click(object sender, EventArgs e)

{ System.Threading.Thread.Sleep(3000); } </script>

AJAX y ASP.NET 26

<html > <head id="Head1" runat="server"> <title>UpdateProgress Example</title> <style type="text/css"> #UpdatePanel1, #UpdatePanel2 { width:200px; height:200px; position: relative; float: left; margin-left: 10px; margin-top: 10px; border-right: gray 1px solid; border-top: gray 1px solid; border-left: gray 1px solid; border-bottom: gray 1px solid; } #UpdateProgress1, #UpdateProgress2 { width: 200px; background-color: #FFC080; position: absolute; bottom: 0px; left: 0px; } </style> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server"> <ContentTemplate> <%=DateTime.Now.ToString() %> <br /> <asp:Button ID="Button1" runat="server" Text="Refresh Panel" OnClick="Button_Click" /> <asp:UpdateProgress ID="UpdateProgress1" AssociatedUpdatePanelID="UpdatePanel1" runat="server"> <ProgressTemplate> UpdatePanel1 updating... </ProgressTemplate> </asp:UpdateProgress> </ContentTemplate> </asp:UpdatePanel> <asp:UpdatePanel ID="UpdatePanel2" UpdateMode="Conditional" runat="server"> <ContentTemplate> <%=DateTime.Now.ToString() %> <br /> <asp:Button ID="Button2" runat="server" Text="Refresh Panel" OnClick="Button_Click"/> <asp:UpdateProgress ID="UpdateProgress2" AssociatedUpdatePanelID="UpdatePanel2" runat="server"> <ProgressTemplate> UpdatePanel2 updating... </ProgressTemplate> </asp:UpdateProgress> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html>

Especificar el diseo del contenido

Si la propiedad DynamicLayout es true, el control UpdateProgress no ocupa espacio inicialmente en la presentacin de la pgina. En su lugar, la pgina cambia dinmicamente para mostrar el contenido del control UpdateProgress cuando es necesario. Para admitir la presentacin dinmica, el control se representa como un elemento <div> cuya propiedad de estilo de presentacin se ha establecido inicialmente en none. Si la propiedad DynamicLayout es false, el control UpdateProgress ocupa espacio en la presentacin de la pgina, aunque no sea visible. En tal caso, el elemento <div> del control tiene la propiedad de estilo de presentacin establecida en block y la visibilidad establecida inicialmente en hidden. Incluir controles UpdateProgress en la pgina Puede colocar los controles UpdateProgress dentro o fuera de los controles UpdatePanel. Un control UpdateProgress se muestra siempre que el control UpdatePanel al que est asociado se actualiza como resultado de una devolucin de datos asincrnica. Esto es as incluso si el control UpdateProgress est dentro de otro control UpdatePanel. Si un control UpdatePanel est dentro de otro panel de actualizacin, una devolucin de datos que se origina dentro del panel secundario genera la presentacin de cualquier control UpdateProgress asociado al panel secundario. Tambin muestra cualquier control UpdateProgress asociado al panel primario. Si una devolucin de datos se origina desde un control secundario inmediato del panel primario, slo se muestran los controles UpdateProgress asociados al panel primario. Este proceso sigue la lgica de la forma de desencadenamiento de las devoluciones de datos.

AJAX y ASP.NET 27

8.- Timer
Es el homlogo del servidor de un cliente creado utilizando el mtodo Window.set.Timeout. EL control Timer provoca un postback segn lo especificado en la propiedad Interval. El postback desencadena un evento Tick. Utilizando el temporizador como un desencadenador de un panel actualizable, podemos actualizar el contenido del panel peridicamente. El control Timer de ASP.NET AJAX realiza devoluciones de datos a intervalos definidos. Si se usa el control Timer con un control UpdatePanel, se pueden habilitar actualizaciones parciales de pginas a un intervalo definido. El control Timer tambin permite enviar la pgina completa. El control Timer se usa para realizar las siguientes acciones:

Actualizar peridicamente el contenido de uno o ms controles UpdatePanel sin actualizar toda la pgina web. Ejecutar cdigo en el servidor cada vez que un control Timer provoque una devolucin de datos. Enviar de forma sincrnica la pgina web completa al servidor web a intervalos definidos.

AJAX y ASP.NET
El control Timer es un control de servidor que incrusta un componente JavaScript en la pgina web. El componente JavaScript inicia la devolucin de datos desde el explorador cuando ha transcurrido el intervalo definido en la propiedad Interval. Las propiedades para el control Timer se definen en el cdigo que se ejecuta en el servidor y se pasan al componente JavaScript. Cuando se usa el control Timer, se debe incluir una instancia de la clase ScriptManager en la pgina web. Cuando el control Timer inicia una devolucin de datos, se genera el evento Tick en el servidor. Se puede crear un controlador de eventos para el evento Tick de forma que realice acciones cuando la pgina se enve al servidor. La propiedad Interval se usa para especificar la frecuencia con la que se producirn las devoluciones y la propiedad Enabled para activar o desactivar el control Timer. La propiedad Interval se define en milisegundos y tiene un valor predeterminado de 60.000 milisegundos (60 segundos). Si se establece la propiedad Interval de un control Timer en un valor pequeo, se puede generar un trfico considerable hacia el servidor web. El control Timer se usa para actualizar el contenido nicamente con la frecuencia que sea necesaria. Se puede incluir ms de un control Timer en una pgina web cuando hay que actualizar distintos controles UpdatePanel a intervalos diferentes. Como alternativa, una nica instancia del control Timer puede ser el desencadenador de ms de un control UpdatePanel en una pgina web. Uso del Timer en un control UpdatePanel Cuando el control Timer se incluye dentro de un control UpdatePanel, el control Timer funciona automticamente como desencadenador para el control UpdatePanel. Este comportamiento se puede invalidar si la propiedad ChildrenAsTriggers del control UpdatePanel se establece en False. Para los controles Timer que se encuentran dentro de un control UpdatePanel, el componente de temporizacin JavaScript se vuelve a crear slo cuando finaliza cada devolucin de datos. Por lo tanto, el intervalo de tiempo no se inicia hasta que la pgina vuelve de la devolucin de datos. Por ejemplo, si la propiedad Interval se establece en 60.000 milisegundos (60 segundos) pero la devolucin de datos tarda 3 segundos en realizarse, la siguiente devolucin de datos se producir 63 segundos despus la anterior. Uso del Timer fuera de un UpdatePanel Cuando el control Timer est fuera de un control UpdatePanel, debe definirse explcitamente el control Timer como un desencadenador para que el control UpdatePanel se actualice.

28

Si el control Timer est fuera de un control UpdatePanel, el componente de temporizacin JavaScript seguir ejecutndose mientras se procesa la devolucin de datos. Por ejemplo, si la propiedad Interval se establece en 60.000 milisegundos (60 segundos) y la devolucin de datos tarda 3 segundos en realizarse, la siguiente devolucin de datos se producir 60 segundos despus la anterior. El usuario ver el contenido actualizado en el control UpdatePanel slo durante 57 segundos. La propiedad Interval debe establecerse en un valor que permita que una devolucin de datos asincrnica se complete antes de que se inicie la siguiente devolucin de datos. Si se inicia una nueva devolucin de datos mientras se est procesando una devolucin de datos anterior, se cancelar la primera devolucin de datos. En el ejemplo de cdigo siguiente se muestra cmo incluir un control Timer dentro de un control UpdatePanel.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager runat="server" ID="ScriptManager1" /> <asp:UpdatePanel runat="server" ID="UpdatePanel1" UpdateMode="Conditional"> <ContentTemplate> <asp:Timer ID="Timer1" runat="server" Interval="120000" OnTick="Timer1_Tick"> </asp:Timer> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html>

AJAX y ASP.NET 29

En el ejemplo siguiente se muestra cmo usar el control Timer fuera de un control UpdatePanel.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server">

<div> <asp:ScriptManager runat="server" ID="ScriptManager1" /> <asp:Timer ID="Timer1" runat="server" Interval="120000" OnTick="Timer1_Tick"> </asp:Timer> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <Triggers> <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" /> </Triggers> <ContentTemplate> <asp:Label ID="Label1" runat="server"></asp:Label> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html>

AJAX y ASP.NET 30

En el ejemplo siguiente se muestra un control UpdatePanel que muestra el precio generado aleatoriamente de una accin y el momento en el que se gener. De forma predeterminada, el control Timer actualiza el contenido del control UpdatePanel cada 10 segundos. El usuario puede decidir actualizar el precio de las acciones cada 10 segundos, cada 60 segundos o no actualizarlo nunca. Cuando el usuario decide no actualizar el precio de las acciones, la propiedad Enabled se establece en false.
<%@ Page Language="C#" AutoEventWireup="true" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html > <head id="Head1" runat="server"> <title>Timer Example Page</title> <script runat="server"> protected void Page_Load(object sender, EventArgs e) { OriginalTime.Text = DateTime.Now.ToLongTimeString(); } protected void Timer1_Tick(object sender, EventArgs e) { StockPrice.Text = GetStockPrice(); TimeOfPrice.Text = DateTime.Now.ToLongTimeString(); } private string GetStockPrice() { double randomStockPrice = 50 + new Random().NextDouble(); return randomStockPrice.ToString("C"); } protected void RadioButton1_CheckedChanged(object sender, EventArgs e) { Timer1.Enabled = true; Timer1.Interval = 10000; }

protected void RadioButton2_CheckedChanged(object sender, EventArgs e) { Timer1.Enabled = true; Timer1.Interval = 60000; } protected void RadioButton3_CheckedChanged(object sender, EventArgs e) { Timer1.Enabled = false; }

AJAX y ASP.NET 31

</script> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <asp:Timer ID="Timer1" OnTick="Timer1_Tick" runat="server" Interval="10000" /> <asp:UpdatePanel ID="StockPricePanel" runat="server" UpdateMode="Conditional"> <Triggers> <asp:AsyncPostBackTrigger ControlID="Timer1" /> </Triggers> <ContentTemplate> Stock price is <asp:Label id="StockPrice" runat="server"></asp:Label><BR /> as of <asp:Label id="TimeOfPrice" runat="server"></asp:Label> <br /> </ContentTemplate> </asp:UpdatePanel> <div> <br /> Update stock price every:<br /> <asp:RadioButton ID="RadioButton1" AutoPostBack="true" GroupName="TimerFrequency" runat="server" Text="10 seconds" OnCheckedChanged="RadioButton1_CheckedChanged" /><br /> <asp:RadioButton ID="RadioButton2" AutoPostBack="true" GroupName="TimerFrequency" runat="server" Text="60 seconds" OnCheckedChanged="RadioButton2_CheckedChanged" /><br /> <asp:RadioButton ID="RadioButton3" AutoPostBack="true" GroupName="TimerFrequency" runat="server" Text="Never" OnCheckedChanged="RadioButton3_CheckedChanged" /> <br /> Page loaded at <asp:Label ID="OriginalTime" runat="server"></asp:Label> </div> </form> </body> </html>

Crear Script de Cliente con la librera de AJAX del lado del cliente
1.- Arquitectura de las caractersticas de AJAX en ASP.NET
La arquitectura de las caractersticas de AJAX en ASP.NET est compuesta de dos partes: bibliotecas de scripts de cliente y componentes de servidor. Estas partes se integran para proporcionar un marco de desarrollo slido. Arquitectura de cliente y servidor de AJAX en ASP.NET

AJAX y ASP.NET 32

La ilustracin muestra la funcionalidad de la Microsoft AJAX Library basada en cliente, incluidas la posibilidad de crear componentes de cliente, compatibilidad de exploradores, conexin de red y servicios principales. La ilustracin tambin muestra la funcionalidad de las caractersticas de AJAX basadas en servidor, incluidos la compatibilidad para scripts, servicios web, servicios de aplicacin y controles de servidor.

2.- Crear Scripts de Cliente


Tres formas de definir scripts de cliente: Definir un bloque de script en la pgina web. Usar la clase ClientScriptManager para aadir dinmicamente javaScript a la pgina Utilizar el control de servidor ScriptManager para registrar JavaScript en la pgina web.

2.1.- Aadir bloque de cdigo a la pgina ASP.NET


Es el mtodo tradicional de trabajo con JavaScript en una pgina web.
<%@ Page Language="C#" AutoEventWireup="true" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html> <head id="Head1" runat="server"> <title>Script Block</title>

AJAX y ASP.NET 33

Podemos aadir bloque de cdigo en la pgina ASP.NET o referenciar a un archivo .js

<script language="javascript" type="text/javascript"> function Collapse() { if (DivCollapse.style.display == "") { DivCollapse.style.display = "none"; document.forms[0].ButtonCollapse.value = "Open"; } else { DivCollapse.style.display = ""; document.forms[0].ButtonCollapse.value = "Close"; } } </script> </head> <body style="font-family: Verdana;"> <form id="form1" runat="server"> <div> <div style="width: 200px; background-color: Blue; color: White; border-style: solid; border-width: thin; border-color: Blue"> <div style="float: left; vertical-align: middle; margintop: 3px;"> Element Title </div> <div style="float: right; vertical-align: middle"> <input id="ButtonCollapse" type="button" value="Close" onclick="Collapse()" /> </div> </div> <div id="DivCollapse" style="width: 200px; height: 200px; border-style: solid; border-width: thin; border-color: Blue"> <div style="margin-top: 20px; text-align: center;"> Content area ... </div> </div> </div> </form> </body> </html>

En el ejemplo anterior el cdigo javaScript est colocado dentro de la pgina, otra posibilidad sera colocar el cdigo JS en un archivo y realizar el enlace
<script type="text/javascript" src="SiteScripts.js"></script>

EN el prximo ejemplo vemos como podemos especificar para que un control de ASP.NET pueda llamar a una funcin javaScript.
<%@ Page Language="C#" AutoEventWireup="true" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server">

AJAX y ASP.NET 34

protected void ButtonCollapse_Click(object sender, EventArgs e) { } </script> <html> <head id="Head1" runat="server"> <title>Script Block</title> <script language="javascript" type="text/javascript"> function Collapse() { if (DivCollapse.style.display == "") { DivCollapse.style.display = "none"; document.forms[0].ButtonCollapse.value = "Open"; } else { DivCollapse.style.display = ""; document.forms[0].ButtonCollapse.value = "Close"; } } </script> </head> <body style="font-family: Verdana;"> <form id="form1" runat="server"> <div> <div style="width: 200px; background-color: Blue; color: White; border-style: solid; border-width: thin; border-color: Blue"> <div style="float: left; vertical-align: middle; margintop: 3px;"> Element Title </div> <div style="float: right; vertical-align: middle"> <asp:button id="ButtonCollapse" runat="server" text="Close" onClientClick="Collapse()" /> </div> </div> <div id="DivCollapse" style="width: 200px; height: 200px; border-style: solid; border-width: thin; border-color: Blue"> <div style="margin-top: 20px; text-align: center;"> Content area ... </div> </div> </div>

</form> </body> </html>

AJAX y ASP.NET 35

Tambien podemos utilizar la propiedad ClientId para cambiar el ID en el cliente.

2.2.- Aadir Script dinmicamente a ASP.NET


Hay veces que necesitaremos generar cdigo JavaScript y aadirlo dinmicamente a la pgina en tiempo de ejecucin. Para ello utilizaremos la clase ClientScriptManager y de esta forma registrar dinmicamente JavaScript. Una instancia de la clase ClientScriptManager se expone a travs de la propiedad ClientScript del objeto Page. Usaremos esta propiedad para aadir JavaScript a la pgina en tiempo de ejecucin, determinar si un script ya ha sido registrado, y otras tareas relacionadas. Para aadir un script, definimos el bloque de cdigo o el archivo con el cdigo. Y llamamos al mtodo RegisterClientScriptBlock del objeto ClientScriptManager.
public void RegisterClientScriptBlock ( Type type, string key, string script, bool addScriptTags

)
type key script Tipo de la secuencia de comandos de cliente que se va a registrar. Clave de la secuencia de comandos de cliente que se va a registrar. Literal de la secuencia de comandos de cliente que se va a registrar.

addScriptTags Valor booleano que indica si se agregan etiquetas de secuencia de comandos.

Una secuencia de comandos de cliente se identifica de forma nica mediante su clave y su tipo. Las secuencias de comandos de la misma clave y tipo se consideran duplicadas. Slo se puede registrar una secuencia de comandos con un par de clave y tipo especficos con la pgina. Al intentar registrar una secuencia de comandos ya registrada no se crea un duplicado de ella. Llame al mtodo IsStartupScriptRegistered para determinar si ya se encuentra registrada una secuencia de comandos de inicio con par de clave y tipo especficos y evitar innecesariamente agregar la secuencia de comandos. En esta sobrecarga del mtodo RegisterClientScriptBlock, puede indicar si la secuencia de comandos proporcionada en el parmetro script se ajusta con un bloque de elemento <script>

mediante el parmetro addScriptTags. El establecimiento del parmetro addScriptTags a true indica que automticamente se agregarn etiquetas de secuencia de comandos. 2.2.1.- RegisterClientScriptBlock El mtodo RegisterClientScriptBlock agrega un bloque de secuencia de comandos a la parte superior de la pgina representada. No se garantiza que los bloques de secuencias de comandos enven los resultados en el orden en que estn registrados
<%@ Page Language="C#"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> public void Page_Load(Object sender, EventArgs e) { // Define the name and type of the client scripts on the page. String csname1 = "PopupScript"; String csname2 = "ButtonClickScript"; Type cstype = this.GetType(); // Get a ClientScriptManager reference from the Page class. ClientScriptManager cs = Page.ClientScript; // Check to see if the startup script is already registered. if (!cs.IsStartupScriptRegistered(cstype, csname1)) { String cstext1 = "alert('Hello World');"; cs.RegisterStartupScript(cstype, csname1, cstext1, true); } // Check to see if the client script is already registered. if (!cs.IsClientScriptBlockRegistered(cstype, csname2)) { StringBuilder cstext2 = new StringBuilder(); cstext2.Append("<script type=\"text/javascript\"> function DoClick() {"); cstext2.Append("Form1.Message.value='Text from client script.'} </"); cstext2.Append("script>"); cs.RegisterClientScriptBlock(cstype, csname2, cstext2.ToString(), false); } } </script> <html > <head> <title>ClientScriptManager Example</title> </head> <body> <form id="Form1" runat="server"> <input type="text" id="Message" /> <input type="button" value="ClickMe" onclick="DoClick()" /> </form> </body> </html>

AJAX y ASP.NET 36

2.2.2.- RegisterClientInclude public void RegisterClientScriptInclude( Type type, string key, string url )

AJAX y ASP.NET 37

Registra la inclusin de la secuencia de comandos de cliente con el objeto Page utilizando un tipo, una clave y una direccin URL. Esta sobrecarga del mtodo RegisterClientScriptInclude acepta los parmetros key y url para identificar la secuencia de comandos, as como un parmetro type para especificar la identificacin de la inclusin de la secuencia de comandos de cliente. Especifique el tipo basndose en el objeto que tendr acceso al recurso. Por ejemplo, cuando se utiliza una instancia de Page para obtener acceso al recurso, se ha de especificar el tipo Page. En el ejemplo de cdigo siguiente se muestra el uso del mtodo RegisterClientScriptInclude. Tenga en cuenta que, aunque se quite la lgica para comprobar la inclusin de secuencias de comandos de cliente existentes, no habr secuencias de comandos de cliente duplicadas en la pgina representada, porque el mtodo RegisterClientScriptInclude comprueba los duplicados. La ventaja de la comprobacin es reducir los clculos innecesarios.
<%@ Page Language="C#"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> public void Page_Load(Object sender, EventArgs e) { // Define the name, type and url of the client script on the page. String csname = "ButtonClickScript"; String csurl = "~/script_include.js"; Type cstype = this.GetType(); // Get a ClientScriptManager reference from the Page class. ClientScriptManager cs = Page.ClientScript; // Check to see if the include script exists already. if (!cs.IsClientScriptIncludeRegistered(cstype, csname)) { cs.RegisterClientScriptInclude(cstype, csname, ResolveClientUrl(csurl)); } } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>ClientScriptManager Example</title> </head> <body> <form id="Form1" runat="server"> <div>

AJAX y ASP.NET
<input type="text" id="Message"/> <input type="button" value="ClickMe" onclick="DoClick()"/> </div> </form> </body> </html>

38

Este ejemplo necesita un javascript llamado script_include.js con el siguiente cdigo:


function DoClick() { Form1.Message.value = 'Text from include script.' }

2.2.3.- RegisterStartupScript Registra la secuencia de comandos de inicio con el objeto Page utilizando un tipo, una clave, un literal de secuencia de comandos y un valor booleano que indican si se agregan etiquetas de secuencia de comandos. public void RegisterStartupScript( Type type, string key, string script, bool addScriptTags ) type Tipo: System.Type Tipo de la secuencia de comandos de inicio que se va a registrar. key Tipo: System.String Clave de la secuencia de comandos de inicio que se va a registrar. script Tipo: System.String Literal de la secuencia de comandos de inicio que se va a registrar. addScriptTags Tipo: System.Boolean Valor booleano que indica si se agregan etiquetas de secuencia de comandos.

Una secuencia de comandos de inicio se identifica de forma nica mediante su clave y su tipo. Las secuencias de comandos de la misma clave y tipo se consideran duplicadas. Slo se puede registrar una secuencia de comandos con un par de clave y tipo especficos con la pgina. Al intentar registrar una secuencia de comandos ya registrada no se crea un duplicado de ella. Llame al mtodo IsStartupScriptRegistered para determinar si ya se encuentra registrada una secuencia de comandos de inicio con par de clave y tipo especficos y evitar innecesariamente agregar la secuencia de comandos.

AJAX y ASP.NET 39

En esta sobrecarga del mtodo RegisterStartupScript, puede indicar si la secuencia de comandos proporcionada en el parmetro script se ajusta con un bloque de elemento <script> mediante el parmetro addScriptTags. El establecimiento del parmetro addScriptTags a true indica que automticamente se agregarn etiquetas de secuencia de comandos. El bloque de secuencia de comandos agregado por el mtodo RegisterStartupScript se ejecuta cuando la pgina termina de cargar pero antes de que se provoque el evento OnLoad de la pgina. No se garantiza que los bloques de secuencias de comandos enven los resultados en el orden en que estn registrados. Si el orden de los bloques de secuencias de comandos es importante, utilice un objeto StringBuilder para reunir las secuencias de comandos en una sola cadena y registrarlas despus en un solo bloque de secuencias de comandos de cliente. En el ejemplo de cdigo siguiente se muestra el uso del mtodo RegisterStartupScript. Observe que el parmetro addScriptTags se establece en false por lo que las etiquetas de secuencia de comandos de apertura y cierra se incluyen con el parmetro script.
<%@ Page Language="C#"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> public void Page_Load(Object sender, EventArgs e) { // Define the name and type of the client scripts on the page. String csname1 = "PopupScript"; String csname2 = "ButtonClickScript"; Type cstype = this.GetType(); // Get a ClientScriptManager reference from the Page class. ClientScriptManager cs = Page.ClientScript; // Check to see if the startup script is already registered. if (!cs.IsStartupScriptRegistered(cstype, csname1)) { String cstext1 = "alert('Hello World');"; cs.RegisterStartupScript(cstype, csname1, cstext1, true); } // Check to see if the client script is already registered. if (!cs.IsClientScriptBlockRegistered(cstype, csname2)) { StringBuilder cstext2 = new StringBuilder(); cstext2.Append("<script type=\"text/javascript\"> function DoClick() {"); cstext2.Append("Form1.Message.value='Text from client script.'} </"); cstext2.Append("script>");

cs.RegisterClientScriptBlock(cstype, csname2, cstext2.ToString(), false); } } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>ClientScriptManager Example</title> </head> <body> <form id="Form1" runat="server"> <input type="text" id="Message" /> <input type="button" value="ClickMe" onclick="DoClick()" /> </form> </body> </html>

AJAX y ASP.NET 40

2.2.4.- RegisterOnSubmitStatement Registra una instruccin OnSubmit con el objeto Page utilizando un tipo, una clave y un literal de secuencia de comandos. La instruccin se ejecuta cuando se enva el objeto HtmlForm. public void RegisterOnSubmitStatement( Type type, string key, string script ) type Tipo: System.Type Tipo de la instruccin OnSubmit que se va a registrar. key Tipo: System.String Clave de la instruccin OnSubmit que se va a registrar. script Tipo: System.String Literal de secuencia de comandos de la instruccin OnSubmit que se va a registrar. Una instruccin OnSubmit se identifica de forma nica mediante su clave y su tipo. Las instrucciones de la misma clave y tipo se consideran duplicadas. Slo se puede registrar una instruccin con un par de clave y tipo especficos con la pgina. Al intentar registrar una instruccin que ya est registrada no se crear un duplicado de ella. Llame al mtodo IsOnSubmitStatementRegistered para determinar si una instruccin OnSubmit ya est registrada con un par de clave y tipo especficos y evitar innecesariamente agregar la secuencia de comandos.

El parmetro script del mtodo RegisterOnSubmitStatement puede contener varios comandos de secuencia de comandos siempre y cuando se delimiten correctamente con un punto y coma (;). El mtodo RegisterOnSubmitStatement agrega una secuencia de comandos que se ejecuta antes de enviar la pgina y le da una oportunidad de cancelar el envo. En el ejemplo de cdigo siguiente se muestra el uso del mtodo RegisterOnSubmitStatement.

AJAX y ASP.NET 41

2.3.- Utilizar el control de servidor ScriptManager para registrar JavaScript en la pgina web
En la mayora de los escenarios, la manera ms fcil de agregar un archivo de script a una pgina ASP.NET es con marcado, como en el ejemplo siguiente: <asp:ScriptManager ID="SMgr" runat="server"> <Scripts> <asp:ScriptReference Path="./Script.js" /> </Scripts> </asp:ScriptManager> Sin embargo, tambin es posible agregar dinmicamente referencias de script. Los desarrolladores de pginas pueden hacer esto para tener ms control sobre cmo se agrega un script. Por ejemplo, podran agregar scripts dinmicamente para ayudar a conservar los recursos de memoria, no cargando una biblioteca de scripts grande a menos que sea necesario. O bien, podran cargar versiones de scripts diferentes para tipos de usuarios diferentes. Los desarrolladores de controles agregan scripts dinmicamente al crear controles de script o controles extensores para dejar disponibles los recursos del script automticamente para la pgina que hospeda el control. Las referencias de script pueden especificar archivos de script o scripts incrustados como recursos en ensamblados. Los scripts se pueden encontrar en las versiones de depuracin y comerciales. El siguiente procedimiento muestra cmo asignar una referencia de script a una pgina en cada una de estas situaciones. Todos los archivos de script que se van a registrar con el control ScriptManager deben llamar al mtodo notifyScriptLoaded para notificar a la aplicacin que el script ha terminado de cargarse. 2.3.1.- Agregar dinmicamente una referencia de script a una pgina 1. 1.- Si no conoce el identificador del elemento <asp:ScriptManager> de la pgina, llame al mtodo ScriptManagerGetCurrent() del control ScriptManager para obtener la instancia actual del control. Compruebe null en caso de que no haya ningn control ScriptManager en la pgina. Si sabe que hay un elemento <asp:ScriptManager> en la pgina y conoce su valor ID, puede omitir este paso. El ejemplo siguiente muestra cmo comprobar la existencia de un control ScriptManager en una pgina y, a continuacin, obtiene la instancia actual o crea una nueva.

// If there is a ScriptManager on the page, use it. // If not, throw an exception. ScriptManager Smgr = ScriptManager.GetCurrent(Page); if (Smgr == null) throw new Exception("ScriptManager not found."); 2.- Crear un objeto ScriptReference. ScriptReference SRef = new ScriptReference();

AJAX y ASP.NET 42

3.- Para los scripts basados en archivos, si sabe que la propiedad ScriptPath del control ScriptManager est establecida en la ubicacin correcta para el archivo de script, establezca la propiedad Name de la instancia ScriptReference en el nombre del archivo de script. En caso contrario, establezca la propiedad Path del objeto ScriptReference en la direccin URL absoluta, relativa o relativa a la aplicacin del archivo de script que desea agregar. // If you know that Smgr.ScriptPath is correct... SRef.Name = "Script.js"; // Or, to specify an app-relative path... SRef.Path = "~/Scripts/Script.js";

4.- Agregue el objeto ScriptReference a la coleccin Scripts del control ScriptManager.


Smgr.Scripts.Add(SRef);

3.- Implementar mediante programacin devoluciones de llamada de cliente sin devoluciones de datos en pginas web de ASP.NET
En el modelo predeterminado para las pginas Web ASP.NET, el usuario interacta con una pgina y hace clic en un botn o realiza alguna otra accin que da como resultado una devolucin de datos. La pgina y sus controles se vuelven a crear, se ejecuta el cdigo de la pgina en el servidor y se representa una nueva versin de la pgina en el explorador. Sin embargo, en algunas situaciones, es til ejecutar cdigo del servidor desde el cliente sin realizar una devolucin de datos. Si la secuencia de comandos de cliente de la pgina incluye informacin de estado (por ejemplo, valores de variables locales), enviar la pgina y obtener una nueva copia ocasiona la destruccin de dicho estado. Adems, las devoluciones de datos de pgina introducen una sobrecarga de procesamiento que puede disminuir el rendimiento y obligar al usuario a esperar a que la pgina se procese y se vuelva a crear. Para evitar la prdida del estado del cliente y no incurrir en la sobrecarga de procesamiento que supone enviar los datos al servidor y esperar a que los devuelva tras procesarlos, puede agregar cdigo a una pgina Web ASP.NET para que pueda realizar devoluciones de llamada del cliente. En una devolucin de llamada del cliente, una funcin de secuencia de comandos de cliente enva una solicitud a una pgina Web ASP.NET. La pgina Web ejecuta una versin modificada de su ciclo de vida normal (se inicia la pgina y se crean sus controles y otros miembros) y, a continuacin, se invoca un mtodo marcado de forma especial. Dicho mtodo realiza el procesamiento especificado en el cdigo y, a continuacin, devuelve al explorador un

valor que otra funcin de secuencia de comandos de cliente puede leer. A lo largo de este proceso, la pgina est activa en el explorador.

AJAX y ASP.NET 43

3.1.- Componentes de las devoluciones de llamada del cliente


La creacin de una pgina ASP.NET que implemente devoluciones de llamada del cliente es una operacin similar a la creacin de cualquier pgina ASP.NET, excepto por unas pocas diferencias. El cdigo de servidor de la pgina debe:

Implementar la interfaz ICallbackEventHandler. Puede agregar esta declaracin de interfaz a cualquier pgina Web ASP.NET. Incluir un mtodo que implemente la interfaz RaiseCallbackEvent. Este mtodo se invocar para realizar la devolucin de llamada del servidor.

Adems, la pgina debe contener tres funciones de secuencia de comandos de cliente que realicen las acciones siguientes:

Una funcin que llama a un mtodo auxiliar que realiza la solicitud real al servidor. En esta funcin, puede incluir lgica personalizada para preparar en primer lugar los argumentos de los eventos y, a continuacin, puede enviar una cadena como parmetro al controlador de eventos de devolucin de llamada del servidor. Otra funcin que recibe (y a la que llama) el resultado del cdigo de servidor que ha procesado el evento de devolucin de llamada y acepta una cadena que representa los resultados. Se denomina funcin de devolucin de llamada del cliente. La tercera funcin es una funcin auxiliar que realiza la solicitud real al servidor, la cual ASP.NET genera automticamente cuando se crea una referencia a esta funcin mediante el mtodo GetCallbackEventReference en el cdigo del servidor.

Las devoluciones de llamadas y de datos del cliente son solicitudes de la pgina originada, as que se graban en los registros de servidor Web como solicitudes de pgina.

3.2.- Implementar las interfaces adecuadas en el cdigo del servidor


Para poder ejecutar correctamente cdigo del servidor desde el cliente sin que se realice ninguna devolucin de datos, debe implementar las interfaces adecuadas en el cdigo del servidor. 3.2.1.- Declarar la interfaz ICallbackEventHandler Puede declarar la interfaz ICallbackEventHandler como parte de la declaracin de clase para la pgina. Si crea una pgina de cdigo subyacente, puede declarar la interfaz utilizando una sintaxis como la siguiente. public partial class CallBack_DB_aspx : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler Si est trabajando en un control de usuario o una pgina de un solo archivo, puede agregar la declaracin mediante una directiva @ Implements en la pgina, como en los ejemplos de cdigo siguientes.

<%@ Page Language="C#" %> <%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>

AJAX y ASP.NET 44

3.2.2.- Crear un mtodo de devolucin de llamada En el cdigo del servidor, debe crear un mtodo que implemente el mtodo RaiseCallbackEvent y un mtodo que implemente el mtodo GetCallbackResult. El mtodo RaiseCallbackEvent toma un nico argumento de cadena en lugar de los dos argumentos que se suelen utilizar con los controladores de eventos. Una parte de este mtodo podra tener la apariencia del ejemplo de cdigo siguiente. public void RaiseCallbackEvent(String eventArgument) { return eventArgument + " new value"; } El mtodo GetCallbackResult no toma ningn argumento y devuelve una cadena. Parte de este mtodo podra ser similar al siguiente ejemplo de cdigo: public string GetCallbackResult() { return aStringValue; }

3.3.- Crear funciones de secuencia de comandos de cliente


Debe agregar funciones de secuencia de comandos de cliente a la pgina para poder realizar dos funciones: enviar la devolucin de llamada a la pgina del servidor y recibir los resultados. Ambas funciones de secuencia de comandos de cliente estn escritas en ECMAScript (JavaScript). 3.3.1.- Enviar la devolucin de llamada La funcin utilizada para enviar la devolucin de llamada se genera en el cdigo del servidor. La devolucin de llamada real la realiza una funcin de biblioteca que est disponible para cualquier pgina que implemente la interfaz ICallbackEventHandler. Para obtener una referencia a la funcin de biblioteca, llame al mtodo GetCallbackEventReference de la pgina, al que se puede obtener acceso a travs de la propiedad ClientScript de la pgina. A continuacin, cree dinmicamente una funcin de cliente que incluya una llamada al valor que devuelve el mtodo GetCallbackEventReference. Pase a dicho mtodo una referencia a la pgina (this en C# o Me en Visual Basic), el nombre del argumento mediante el que pasar los datos, el nombre de la funcin de secuencia de comandos de cliente que recibir los datos de la devolucin de llamada y un argumento que pasa el contexto deseado. Cuando haya creado la funcin, insrtela en la pgina llamando al mtodo RegisterClientScriptBlock. En el ejemplo de cdigo siguiente se muestra cmo crear dinmicamente una funcin denominada CallServer que invoca la devolucin de llamada.

AJAX y ASP.NET
void Page_Load(object sender, EventArgs e) { ClientScriptManager cm = Page.ClientScript; String cbReference = cm.GetCallbackEventReference(this, "arg", "ReceiveServerData", ""); String callbackScript = "function CallServer(arg, context) {" + cbReference + "; }"; cm.RegisterClientScriptBlock(this.GetType(), "CallServer", callbackScript, true); }

45

Los nombres de los argumentos aceptados por la funcin que est generando deben coincidir con los nombres de los valores pasados al mtodo GetCallbackEventReference. En el ejemplo de cdigo siguiente se muestra marcado que se puede utilizar para invocar la devolucin de llamada y procesar su valor devuelto <input type="button" value="Callback" onclick="CallServer(1, alert('Callback'))"/> <br /> <span id="Message"></span> 3.3.2.- Recibir la devolucin de llamada Puede escribir una funcin de cliente que reciba las devoluciones de llamada de forma esttica en la pgina. El nombre de la funcin debe coincidir con el nombre pasado en la llamada al mtodo GetCallbackEventReference. La funcin receptora acepta dos valores de cadena: uno para el valor devuelto y un segundo valor opcional para el valor de contexto que se devuelve del servidor. La funcin podra ser similar al siguiente ejemplo de cdigo: <script type="text/javascript"> function ReceiveServerData(arg, context) { Message.innerText = 'Processed callback.'; } </script>

3.4.- Ejemplo de implementacin de devolucin de llamada de cliente


El ejemplo de cdigo siguiente se compone de dos partes. La primera parte muestra una pgina Web ASP.NET (la pgina .aspx). La segunda parte muestra el archivo de cdigo subyacente correspondiente (el archivo .aspx.cs). La pgina Web emula una bsqueda de base de datos para determinar el nmero de elementos disponibles, o en existencias, para una serie de productos (monitores, teclados, etc.). Para simplificar este ejemplo de cdigo, la base de datos est representada por una lista de diccionario que contiene un pequeo grupo de elementos. Para cada elemento de la tabla,

la clave es el nombre del elemento (por ejemplo, monitor) y el valor es el nmero de elementos que hay en existencias. En una aplicacin de produccin, se utilizara una base de datos.

AJAX y ASP.NET 46

Cuando se ejecuta la pgina, se enlaza un control ListBox a la tabla hash para que el control ListBox muestre la lista de productos. La pgina tambin contiene un elemento button (no un control de servidor Web de botn), cuyo evento onclick est enlazado a una funcin del cliente denominada LookUpStock. Cuando los usuarios hacen clic en el botn, ste ejecuta la funcin LookUpStock, que obtiene la seleccin actual del cuadro de lista y, a continuacin, realiza la devolucin de llamada del cliente llamando a la funcin CallServer. La pgina de cdigo subyacente agrega secuencias de comandos de cliente a la pgina a travs del mtodo RegisterClientScriptBlock. La secuencia de comandos que se agrega a la pgina incluye una funcin denominada CallServer, que obtiene el nombre del mtodo que realiza la devolucin de datos al servidor desde el mtodo GetCallbackEventReference. La devolucin de llamada del cliente invoca al mtodo RaiseCallbackEvent, que devuelve las existencias disponibles para el producto deseado. Tenga en cuenta que los argumentos enviados entre la secuencia de comandos de cliente y el cdigo del servidor slo pueden ser cadenas.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="WebApplication1.WebForm2" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server"> <script type="text/javascript"> function LookUpStock() { var lb = document.forms[0].ListBox1; var product = lb.options[lb.selectedIndex].text CallServer(product, ""); } function ReceiveServerData(rValue) { Results.innerText = rValue; } </script> </head> <body> <form id="form1" runat="server" submitdisabledcontrols="False"> <div> <asp:ListBox ID="ListBox1" Runat="server"></asp:ListBox> <br /> <br /> <br /> <br /> Items in stock: <span ID="Results"></span> <br /> </div> </form>

<button onclick="LookUpStock()">Look Up Stock</button> </body> </html>

AJAX y ASP.NET 47

using using using using using using using using using using

System; System.Data; System.Configuration; System.Collections; System.Web; System.Web.Security; System.Web.UI; System.Web.UI.WebControls; System.Web.UI.WebControls.WebParts; System.Web.UI.HtmlControls;

namespace WebApplication1 { public partial class WebForm2 : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler

{ protected System.Collections.Specialized.ListDictionary catalog; protected void Page_Load(object sender, EventArgs e) { String cbReference = Page.ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context"); String callbackScript; callbackScript = "function CallServer(arg, context)" + "{ " + cbReference + "} ;"; Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", callbackScript, true); catalog = new System.Collections.Specialized.ListDictionary(); catalog.Add("monitor", 12); catalog.Add("laptop", 10); catalog.Add("keyboard", 23); catalog.Add("mouse", 17); ListBox1.DataSource = catalog; ListBox1.DataTextField = "key"; ListBox1.DataBind(); }

#region Miembros de ICallbackEventHandler #endregion #region Miembros de ICallbackEventHandler public string GetCallbackResult() { return returnValue;

} #endregion #region Miembros de ICallbackEventHandler

AJAX y ASP.NET 48

String returnValue; void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument) { if (catalog[eventArgument] == null) { returnValue = "-1"; } else { returnValue = catalog[eventArgument].ToString(); } } #endregion } }

3.- Leer Tiempo del Servidor usando Callback


Usando callbacks podemos desde el cdigo del servidor leer el resultado de una funcin JavaScript. Elaborar una respuesta, y con este resultado actualizar la pgina ASP sin postback. Bsicamente, un callback es un dialogo entre el cdigo JavaScript de la pgina y el cdigo .NET del servidor. Para usar un Callback de ASP.NET 2.0 necesitamos usar el siguiente esquema, siendo el mismo para cualquier solucin:

1. Implementar la interfaz ICallbackEventHandler 2. Configurar las retrollamadas en Page_Load 3. Escribir respuesta en RiseCallbackEvent, proceso de negocios 4. Enviar respuesta en GetCallbackResult 5. Escribir respuesta en la pgina

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="tiemposervidorcallback._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Diferencia Horaria</title> <script type="text/javascript" src="ClientTime.js"></script> <script type="text/javascript" src="CallbackComplement.js"></script> <script type="text/javascript"> function timerEvent() { callServerTask(); window.setTimeout("timerEvent()",1500); return false; } </script> </head> <body onload="window.setTimeout('timerEvent()',1500);"> <form id="form1" runat="server"> <div> <h2> Diferencia Horaria</h2> <hr /> <div id="div_CallbackResult"> <asp:TextBox ID="txtClientTime" runat="server" Width="343px" /> <br /> <asp:TextBox ID="txtServerTime" runat="server" Width="341px" /> </div> <hr /> </div> </form> </body> </html>

AJAX y ASP.NET 49

Notamos que se invoca una funcin JavaScript de nombre callServerTask la cual no existe en la pgina. La funcin callServerTask ser escrita por el cdigo del lado del servidor.

1. Implementar la interfaz ICallbackEventHandler


La implementacin de la interfaz ICallbackEventHandler capacita a la pgina Web a usar Callbacks de ASP.NET 2.0. La interfaz habilita los eventos: RaiseCallbackResult y GetCallbackResult los cuales se configuran para usar dos subrutinas de JavaScript, una que llama a RaiseCallbackResult y la otra que toma una respuesta elaborada enviada por GetCallbackResult. Implementamos la interfaz al heredar de ICallbackEventHandler en C#, o al agregar la directiva Implements ICallbackEventHandler en VB.NET. Se recomienda que siempre se agregue la variable a nivel de modulo de nombre _callbackResult para C# o m_CallbackResult para VB.NET. Aunque el nombre es a libre

albedrio, podemos generalizar un nombre para simplificar el asunto. As, el cdigo de GetCallbackResult() puede ser el mismo en cada aplicacin que use callbacks, solo se hace un retorno de m_CallbackResult.

AJAX y ASP.NET 50

2. Configurar las retrollamadas en Page_Load


La configuracin del callback se hace en el evento Page_Load. Debemos generar una lnea de cdigo que se agregar dinmicamente a la pgina y es la encargada del callback. ASP.NET facilita esto a travs del metodo GetCallbackEventReference. Atencin a los argumentos de GetCallbackEventReference. El primero es el objeto contenedor, es decir, this para C#, y Me para VB.NET. El segundo, clientTime('') en el ejemplo, es argumento el cual ser pasado a RaiseCallbackEvent. Este argumento puede variar segn el contexto de la aplicacin. El tercer argumento, putCallbackResult, es la funcin que se invocar desde GetCallbackResult pasando m_CallbackResult como argumento de putCallbackResult, es decir, se pasan datos del cdigo del servidor al cdigo del cliente. Los dems argumentos son opcionales. En particular, es conveniente agregar una funcin que reporte un posible error en el callback. Se ha generalizado este nombre a clientErrorCallback. Al final de Page_Load usamos RegisterClientScriptBlock el cual es el mtodo encargado de enviar la fuente de texto script a la pagina. Normalmente en al final de Page_Load agregamos un atributo a un control para habilitar un evento que ser el responsable de llamar la funcion callServerTask(). En este caso no es necesario ya que callServerTask() es llamada desde la function timerEvent(). El resultado de GetCallbackEventReference se puede visualizar en el cdigo de la pagina leida por el visualizador de internet. Realmente la complejidad no es algo que nos deba preocupar. He aqu el cdigo generado a manera de ilustracin:
function callServerTask() { WebForm_DoCallback('__Page',clientTime(''), putCallbackResult,null,clientErrorCallback,true); }

3. Escribir respuesta en RiseCallbackEvent


RiseCallbackEvent es una funcin que se invoca desde la pgina al servidor sin postbak. Un script de JavaScript coloca el argumento eventArgument de RiseCallbackEvent el cual es una cadena de texto de JavaScript. En RiseCallbackEvent procesamos esta cadena para generar una respuesta HTML. En una aplicacin de produccin, eventArgument suele contener el valor de una clave para filtrar una vista de datos. En seguida procesamos eventArgument, es decir hacemos lo que en ingles se conoce como parsing, que no es ms que extraer informacin de una cadena de texto. Luego elaboramos una respuesta HTML.

4. Enviar respuesta en GetCallbackResult

AJAX y ASP.NET 51

La cadena o fuente HTML generada como respuesta es asignada a m_CallbackResult, la cual a su vez es retornada inmediatamente a la pagina a travs de GetCallbackResult.

5. Escribir respuesta en la pgina


La pagina ahora tiene el resultado del callback en la variable m_CallbackResult que ahora es un argumento de putCallbackResult, y este escribe la division 'div_CallbackResult'. El nombre 'div_CallbackResult' tambin es definido por el programador. Como se ha venido comentando, si usamos un nombre generalizado como 'div_CallbackResult' podemos hacer ms simple la programacin AJAX. He usado una etiqueta DIV la cual encierra toda la respuesta HTML. No necesariamente tiene que ser una etiqueta DIV, puede ser cualquier objeto HTML. Solo se trata de generalizar para simplificar. Para hacer simplificar cdigo en la pgina las funciones putCallbackResult y clientErrorCallback se pueden colocar en un archivo JScript e incrustar en la pgina con una directiva src. El archivo ser un tem ms de la aplicacin Web. Se ha llamado a este archivo CallBackComplement.js. He aqu su cdigo:
// JScript File function putCallbackResult( callbackResult ) { var info = document.getElementById('div_CallbackResult'); info.innerHTML = callbackResult; } function clientErrorCallback( error, context ) { alert('Callback failed! ' + error); }

Serializacin JSON

JSON (notacin de objetos JavaScript) es un formato de codificacin de datos eficaz que permite intercambios rpidos de cantidades pequeas de datos entre los exploradores de cliente y servicios web con AJAX (JavaScript asincrnico y XML) habilitado. En este tema se muestra cmo serializar objetos de tipo .NET en datos codificados mediante JSON y, a continuacin, deserializar los datos en formato JSON en instancias de tipos .NET mediante el DataContractJsonSerializer. En este ejemplo, se usa un contrato de datos para mostrar la serializacin y deserializacin de un tipo Person definido por el usuario.

Para definir el contrato de datos de una Persona


Defina el contrato de datos para Person asociando DataContractAttribute a la clase y el atributo DataMemberAttribute a los miembros que desee serializar.

[DataContract] internal class Person { [DataMember] internal string name; [DataMember] internal int age; }

AJAX y ASP.NET 52

Agregaremos una referencia a System.ServiceModel.Web y a System.Runtime.Serialization E incluiremos using System.Runtime.Serialization.Json; using System.Runtime.Serialization;

Para serializar una instancia de tipo Persona a JSON


Cree una instancia del tipo Person.
Person p = new Person(); p.name = "John"; p.age = 42;

Serialice el objeto Person a una secuencia de memoria utilizando el DataContractJsonSerializer.


MemoryStream stream1 = new MemoryStream(); DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person));

Utilice el mtodo WriteObject para escribir datos JSON en la secuencia.


ser.WriteObject(stream1, p);

Muestre la salida JSON.


stream1.Position = 0; StreamReader sr = new StreamReader(stream1); Mensaje.Text=sr.ReadToEnd();

Deserializacin de una instancia de tipo Persona a partir de JSON

Deserialice los datos codificados con JSON en una nueva instancia de Person utilizando el mtodo ReadObject de DataContractJsonSerializer:
stream1.Position = 0; Person p2 = (Person)ser.ReadObject(stream1);

AJAX y ASP.NET 53

Muestre los resultados.


Mensaje2.Text=p2.name; Mensaje2.Text+="\r\n, age="; Mensaje2.Text=p2.age.ToString();

El ASP.NET AJAX Control Toolkit


Accordion

El control Web Accordion te permite ubicar mltiples paneles, de modo que nicamente uno ser visible en cada momento. Dichos paneles son los AccordionPane, de los que debemos definir la cabecera (Header) y el contenido (Content). El estado del Accordion es guardado, de modo que el AccordionPane activo se mantendr visible a travs de los postbacks. 9 propiedades definen al Accordion: SelectedIndex: Define el AccordionPane que estar activo por defecto, donde el primero tiene como ndice 0. Es opcional y por defecto vale 0. HeaderCssClass / ContentCssClass: Identifica el nombre de la clase CSS utilizada para las cabeceras/contenidos (Header/content). Si se define como atributo del Accordion, la clase se aplicar por defecto a todos los AccordionPane de que est compuesto. Tambin se puede definir individualmente como atributo de cada AccordionPane. FadeTransitions: en caso de ser true se aplicacar un efecto de fading en la transicin, en caso de ser false la transicin se realizar de modo normal. Es optativo y por defecto vale false. TransitionDuration: cantidad de milisegundos que definen la duracin de una transicin. Se consigue un efecto muy agradeble con transicin de unos 200-300 milisegundos. FramesPerSecond: nmero de frames por segundo que se usar en la animacin de las transiciones. Suele ser suficiente un nmero superior a 40. AutoSize: define la restriccin en la altura del Accordion. Puede tomar tres valores: o None: No tiene ninguna restriccin. La altura del Accordion no tiene lmite. Es importante resear que esto puede implicar que otros elementos de la misma Web sean movidos. o Limit: como mximo, el Accordion medir lo que marque la propiedad Height. Si el Accordion es ms alto de lo que marque su Height, al AccordionPane activo se le aadir un scroll para ajustarse al lmite. En caso de ser menor a ese lmite el Accordion no sufre cambios. o Fill: el Accordion siempre medir lo que marqu su propiedad Height, expandiendo o minimizando el contenido en base a las necesidades. Header: es una propiedad del AccordionPane y define el valor de su cabecera.

Content: es una propiedad del AccordionPane y define el valor de su contenido. DataSource: El DataSource a aplicar (totalmente optativo). Para una correcta aplicacin hay que llamar a DataBind(). DataSourceID: Alternativamente, poder asignar el identificador de nuestra fuente de datos. DataMember: el miembro a enlazar cuando se usa el DataSourceID.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ACT-Accordion.aspx.cs" Inherits="Accordion_ACT_Accordion" %> <%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Accordion</title> <style> .accordionCabecera { border: 1px solid black; background-color: #ffd800; font-family: Arial, Sans-Serif; font-size: 14px; font-weight: bold; padding: 4px; margin-top: 4px; cursor: pointer; } .accordionContenido { font-family: Sans-Serif; background-color: #fff8ab; border: 1px solid black; border-top: none; font-size: 12px; padding: 7px; } </style>

AJAX y ASP.NET 54

</head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager id="ScriptManager" runat="server" /> <ajaxToolkit:Accordion ID="Accordion1" runat="server" FadeTransitions="True" FramesPerSecond="50"

Width="250px" TransitionDuration="200" HeaderCssClass="accordionCabecera" ContentCssClass="accordionContenido"> <Panes> <ajaxToolkit:AccordionPane ID="AccordionPane1" runat="server"> <Header>Panel 1</Header> <Content>Contenido 1</Content> </ajaxToolkit:AccordionPane> <ajaxToolkit:AccordionPane runat="server"> <Header>Panel 2</Header> <Content>Contenido 2</Content> </ajaxToolkit:AccordionPane> <ajaxToolkit:AccordionPane runat="server"> <Header>Panel 3</Header> <Content>Contenido 3</Content> </ajaxToolkit:AccordionPane> </Panes> </ajaxToolkit:Accordion>

AJAX y ASP.NET 55

</div> </form> </body> </html>

AlwaysVisibleControl
Descripcin
El AlwaysVisibleControl es uno de los controles Web del ASP.NET AJAX Control Toolkit ms simples. Su funcionalidad consiste en dejar clavado el contenido en un punto especfico de la pgina. Un ejemplo sera el que cierto mensaje se muestre siempre en la parte inferior derecha de nuestra pgina, y que se mantenga en la misma posicin de la pantalla del usuario cuando se haga scroll sobre la pgina.

Propiedades
TargetControlID: ID del control que queremos que el AlwaysVisibleControl clave en la posicin que determinemos. Habitualmente suele tratarse de un Panel. HorizontalSide: ubicacin horizontal (derecha o izquierda) donde se clavar el control. Es una propiedad optativa que por defecto vale left. HorizontalOffset: distancia horizontal en pixels desde el objeto hasta el lado que definamos en el HorizontalSide. Es optativo y por defecto vale 0 px. VerticalSide: ubicacin vertical (arriba o abajo) donde se clavar el control. Es una propiedad optativa que por defecto vale top. VerticalOffset: distancia vertical en pixels desde el objeto hasta el lado que definamos en el VerticalSide. Es optativo y por defecto vale 0 px. ScrollEffectDuration: define la cantidad de segundos entre que la pgina hace scroll hasta que el control se posiciona donde definamos. Por defecto vale 0.1 segundos y siempre debe ser mayor que cero.

Ejemplo

AJAX y ASP.NET 56

<asp:Panel ID="Panel1" runat="server" Height="50px" Width="125px"> de mensaje </asp:Panel> <ajaxToolkit:AlwaysVisibleControlExtender ID="AlwaysVisibleControlExtender1" runat="server" TargetControlID="Panel1" VerticalSide="Bottom" VerticalOffset="10" HorizontalSide="Right" HorizontalOffset="10" ScrollEffectDuration="0.0001"> </ajaxToolkit:AlwaysVisibleControlExtender>

Animation
Y para el final dejamos dos controles que son, sin duda alguna, los ms espectaculares del ASP.NET AJAX Control Toolkit. El primero de todos es el Animation. El Animation es un extendedor que permite aplicar sobre el elemento elegido las animaciones que nos permiten el Animation Framework. El Animation Framework es una aquitecturo de animaciones creadas para ASP.NET AJAX y que, a pesar de no ser demasiado complicadas, mereceran un artculo completo para su correcta explicacin. A modo de tanteo, diremos que las animaciones proporcionadas por el Animation Framework y que podremos aplicar con nuestro extendedor Animation, nos permiten asignar efecto de fadeIn y fadeOut, pulse, Scale o acciones javascript, tanto en modo secuencia, en modo paralelo o cualquier combinacin imaginable de las dos.

Propiedades
TargetControlID: ID del control a partir del cual y sobre el cual vamos a aplicar las animaciones. OnLoad: elemento bajo el cual aadiremos las animaciones que se iniciarn tras la carga del control. OnClick: elemento bajo el cual aadiremos las animaciones que se iniciarn hacer click sobre el control. OnMouseOver: elemento bajo el cual aadiremos las animaciones que se iniciarn tras pasar el mouse sobre el control. OnMouseOut: elemento bajo el cual aadiremos las animaciones que se iniciarn tras sacar el mouse de encima del control. OnHoverOver: Similar a OnMouseOver, solo que parar la animacin OnHoverOut antes de ejecutarse. OnHoverOut: Similar a OnMouseOut, solo que parar la animacin OnHoverOver antes de ejecutarse. Apliquemos el uso del control Animation. Para aprender a usar animaciones, se recomienda visitar la web oficial, donde encontraremos ejemplos de uso y una referencia completa: - http://ajax.asp.net/ajaxtoolkit/Walkthrough/UsingAnimations.aspx - http://ajax.asp.net/ajaxtoolkit/Walkthrough/AnimationReference.aspx

Ejemplo

<asp:Panel ID="Panel1" runat="server" Width="125px" BorderWidth="1px" BackColor="Yellow"> Pasa por encima mo y luego vete. Tambin puedes hacerme clic ;) </asp:Panel> <ajaxToolkit:AnimationExtender id="MyExtender" runat="server" TargetControlID="Panel1"> <Animations> <OnMouseOver> <FadeOut Duration="2.5" Fps="20" /> </OnMouseOver> <OnMouseOut> <FadeIn Duration=".5" Fps="20" /> </OnMouseOut> <OnClick> <Sequence> <Pulse Duration=".1" /> <Parallel Duration=".5" Fps="30"> <FadeOut /> <Scale ScaleFactor="5" Unit="px" Center="true" ScaleFont="true" FontUnit="pt" /> </Parallel> </Sequence> </OnClick> </Animations> </ajaxToolkit:AnimationExtender>

AJAX y ASP.NET 57

Calendar
Calendar es un extensor ASP.NET AJAX que se puede conectar a cualquier TextBox de ASP.NET de control. Ofrece al cliente la fecha la recoleccin de lado la funcionalidad con la fecha personalizable formato y la interfaz de usuario en un control de ventanas emergentes. Usted puede interactuar con el calendario haciendo clic en el da a fijar la fecha, o el "Hoy" para establecer la fecha actual. Adems, las flechas izquierda y derecha se puede utilizar para avanzar o retroceder un mes. Al hacer clic en el ttulo del calendario que puede cambiar la vista de los Das en la mes en curso, a meses en el ao en curso. Otro clic va a cambiar a los aos En la dcada actual. Esta accin le permite saltar fcilmente a las fechas en el pasado o en el futuro desde el control de calendario.

TargetControlID - El ID del cuadro de texto para ampliar con el calendario. la CssClass - Nombre de la clase CSS utilizado para el estilo del calendario. Ver seccin del Calendario Tematizacin para ms informacin. Formato - Formato de cadenas se utiliza para mostrar la fecha seleccionada. PopupButtonID - La identificacin de un control para mostrar la ventana emergente de calendario de cuando se hace clic. Si este valor no est establecido, el calendario aparecer en el cuadro de texto recibe el foco. en el BottomLeft PopupPosition - Indica que el calendar popup debe aparecer (por defecto), BottomRight, topLeft, topright, izquierda o derecha del cuadro de texto. SelectedDate - Indica la fecha del calendario es el extensor inicializa con.

AsyncFIleUpload

AJAX y ASP.NET 58

AsyncFileUpload es un control de ASP.NET AJAX que permite subir archivos de forma asncrona con el servidor. El archivo de los resultados de la carga se puede comprobar tanto en el servidor y los lados del cliente. Puede guardar el archivo cargado llamando a la SaveAs () en un controlador para el de servidor UploadedComplete. evento

Eventos

UploadedComplete - Dispar contra el lado del servidor cuando el archivo cargado correctamente UploadedFileError - Es despedido en el lado del servidor cuando el archivo uloaded est daado

Propiedades

CompleteBackColor - Color de fondo del control sobre la carga completa. El valor por defecto -- 'Cal'. ContentType - Obtiene el tipo de contenido MIME de un archivo enviado por un cliente. ErrorBackColor - Color de fondo del control en caso de error de carga. El valor por defecto -- 'Rojo'. FileContent - Obtiene un Corriente objeto que apunta a un archivo subido a prepararse para leer el contenido del archivo. NombreDeArchivo - Obtiene el nombre de un archivo en un cliente a cargar con el control. HasFile - Obtiene un bool valor que indica si el control contiene un archivo. OnClientUploadComplete - El nombre de una funcin de JavaScript ejecutado en el lado del cliente despus de que el archivo subido correctamente OnClientUploadError - El nombre de una funcin de JavaScript ejecutado en el lado del cliente si la carga de archivos no OnClientUploadStarted - El nombre de una funcin de JavaScript ejecutado en el lado del cliente en la carga de archivos iniciado PostedFile - Obtiene un HttpPostedFile objeto que proporciona acceso al archivo cargado. ThrobberID - ID de control que se muestra mientras el archivo se carga. UploaderStyle - Estilo de la apariencia del control (tradicional, moderna). El valor por defecto -- "Tradicional". UploadingBackColor - Color de fondo del control cuando la carga est en progreso. El valor por defecto -- 'Blanco'. Anchura - Ancho del control (Unidad). El valor por defecto -- '355px '.

Mtodos

SaveAs (cadena nombre de archivo) - Guarda el contenido de un archivo cargado.

AJAX y ASP.NET 59

CascadingDropDown
Imaginemos un escenario en que tenemos 3 listas desplegables. La primera de ellas tiene unos items determinados, pero la segunda lista depende del valor que se le d a la primera y la tercera lista del valor que se le d a la segunda. Hasta ahora tenamos dos opciones: - Implementar una compleja serie de funciones javascript, - Utilizar ASP.NET recargando las pginas. En el primer caso quedaba muy profesional de cara al cliente, pues ste manejaba muchos datos de forma muy rpida y sin recargar la pgina... sin embargo era muy poco profesional del cara al programador pues la complejidad en el javascript se incrementaba exponencialmente. En el segundo caso el programador consegua una programa estable, rpido y fcilmente modificable, pero el usuario vea cmo se recargaba la pgina entera cada vez que elega una opcin diferente. Pues bien, con el CascadingDropDown solucionamos los problemas y nos quedamos con las ventajas: no se recargar la pgina y se definir el contenido de los DropDownList mediante ASP.NET

Propiedades
TargetControlID: el ID de la lista desplegable a la que se aplicar. Category: se define como el nombre de la categora que la lista desplegable representa. Su utilidad ser la de representar uno de los dos parmetros de entrada al ServiceMethod que estudiaremos posteriormente PromptText: es un texto opcional que ver el usuario cuando la lista desplegable est vaca. LoadingText: tambin es un texto opcional que ver el usuario cuando el dato se est cargando. ServicePath: define el path del servicio web que devuelve la informacin que se usar para rellenar la lista desplegable. Si el servicio web se encuentra en la propia pgina en que estamos trabajando, no pondremos nada en esta propiedad. ServiceMethod: le dedicamos un apartado exclusivo ParentControlID: ID de la lista desplegable de cuya seleccin depende esta lista desplegable. En nuestro ejemplo, si esta es la lista desplegable 2, el ParentControlID apuntara a la lista desplegable 2. Gracias a ParentControlId creamos una jerarqua de listas desplegables. En caso de estar en lo ms alto de la jerarqua no pondramos nada. SelectedValue: valor que vendra seleccionado por defecto. Es opcional.

ServiceMethod

AJAX y ASP.NET 60

El es la funcin a la que se llamar para rellenar la lista desplegable. Tendr el siguiente aspecto: [WebMethod] public CascadingDropDownNameValue[] GetDropDownContents(string knownCategoryValues, string category){...} ...donde lo nico que se podr cambiar ser el nombre de la funcin, pues el resto debe ser igual. Observamos que: La funcin debe ir precedida por [WebMethod]. CascadingDropDownNameValue es un tipo de dato dentro del namespace AjaxControlToolkit (que en nuestro ejemplo suponemos ya importado mediante using (C#) o import (VB)). El segundo parmetro (category) se corresponde con el atributo Category que hemos indicado en nuestro control CascadingDropDown. Mencin especial merece el primer parmetro. En ste se almacena el valor seleccionado de cada una de las listas desplegables predecesoras en la jerarqua. Siguiendo con nuestro ejemplo, si estuviramos dentro del definido en la lista desplegable 3, el contenido del primer parmetro sera similar a: Category1:valor1;category2:valor2 Pero no cabe asustarse, no hace falta que parseemos a mano esa informacin, pues dispondemos del mtodo ParseKnownCategoryValuesString que har ese trabajo por nosotros, de modo que haciendo: StringDictionary knownCategoryValuesDictionary = AjaxControlToolkit .CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues); ... obtenemos un StringDictionary bien ordenado y sencillo de utilizar. Nota 1: hay que importar los siguientes namespaces: - System.Web.Services - AjaxControlToolkit - System.Collections.Specialized Nota 2: EnableEventValidation debe valer false El uso avanzado del CascadingDropDownList implica un estudio ms en profundidad de todas sus caractersticas. En los diferentes blogs tecnolgicos encontramos diferentes ejemplos en los que se configura la fuente de datos de diferentes listas desplegables mediante XML o ases de datos. Nosotros mostramos un sencillo ejemplo para que el lector se agilice en el uso del CascadingDropDown y pueda acceder a ejemplos mucho ms complejos. Nuestro ejemplo consta de dos listas desplegables, donde la segunda depende de la primera.

Ejemplo

En el momento hacemos una seleccin en la primera lista desplegable el mecanismo del CascadingDropDown entra en funcionamiento y se rellena la segunda lista desplegable sin que la pgina se recargue. CascadingDropDown.aspx <atlas:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true"> </atlas:ScriptManager> <asp:DropDownList ID="DropDownList1" runat="server"> <asp:ListItem Text="Elige tu humor y te aconsejar tu color" Value="-1"> </asp:ListItem> <asp:ListItem Text="Triste" Value="Triste"> </asp:ListItem> <asp:ListItem Text="Alegre" Value="Alegre"> </asp:ListItem> </asp:DropDownList> <br /> <asp:DropDownList ID="DropDownList2" runat="server"> </asp:DropDownList> <br /> <ajaxToolkit:CascadingDropDown ID="CascadingDropDown2" runat="server" TargetControlID="DropDownList2" Category="color" ServiceMethod="" ParentControlID="DropDownList1"> </ajaxToolkit:CascadingDropDown> CascadingDropDown.aspx.cs [WebMethod] public CascadingDropDownNameValue[] (string knownCategoryValues, string category) { CascadingDropDownNameValue[] respuesta = new AjaxControlToolkit .CascadingDropDownNameValue[2]; if (category == "color") { StringDictionary knownCategoryValuesDictionary = AjaxControlToolkit .CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues); if (DropDownList1.SelectedValue != "-1") { if (DropDownList1.SelectedValue == "Alegre") { respuesta[0] = new CascadingDropDownNameValue("Amarillo", "Amarillo"); respuesta[1] = new CascadingDropDownNameValue("Naranja", "Naranja"); } else if (DropDownList1.SelectedValue == "Triste") {

AJAX y ASP.NET 61

respuesta[0] = new CascadingDropDownNameValue("Gris", "Gris"); respuesta[1] = new CascadingDropDownNameValue("Azul marino", "Azul_marino"); } } } return respuesta; }

AJAX y ASP.NET 62

CollapsiblePanel
Con el CollapsiblePanel conseguiremos que cualquier control ASP.NET pueda ser maximizado o minimizado a nuestro antojo. Distinguiremos entre el contenido, que ser el control que vaya a cerrarse y abrirse (por ejemplo un Panel) y el controlador, que ser el control sobre el que deberemos hacer clic para cerrar y/o abrir el contenido. El estado del contenido (abierto o cerrado) es guardado a lo largo de los postbacks, por lo que permanecer igual cuando recarguemos una pgina. Adems, podemos especificar si queremos que el contenido tenga una altura y/o anchura determinadas, o por el contrario permitimos que se dimensione como requiera.

Propiedades
TargetControlID: el ID del control Web correspondiente al contenido. CollapsedSize: el tamao en pixels del contenido cuando est cerrado. Lo habitual es ponerlo a 0, de modo que queda totalmente cerrado. ExpandedSize: el tamao en pixels del contenido cuando est abierto. Collapsed: especifica el estado del contenido cuando se inicializa la pgina. Puede ser collapsed (cerrado) o expanded (abierto). Scroll Contents: si especificamos true, se aadir una barra de scroll cuando el tamao sobrepaso al especificado en CollapsedSize y ExpandedSize. Si no queremos que se produzca ningn efecto, lo pondremos a false. ExpandControlID/CollapseControlID: el ID del control Web correspondiendo al controlador. Como vemos podemos elegir un controlador que maximice el contenido y otro que lo minimice. Habitualmente ambos atributos apuntan al mismo controlador. TextLabelID: el ID de la Label donde se especificar el estado en que se encuentra el contenido (ver las dos prximas propiedades). CollapsedText: texto que se mostrar en la Label especificada en TextLabelId cuando el controlador est cerrado. ExpandedText: texto que se mostrar en la Label especificada en TextLabelId cuando el controlador est abierto. ImageControlID: En lugar de un texto, podemos especificar una imagen para que sea sta la que describa el estado en que se encuentra el contenido. Si adems tambin hemos especificado un texto, ste se corresponder con el texto alternativo de la imagen (el atributo alt). CollapsedImage: Path que apunta a la imagen que se mostrar cuando el contenido est minimizado. ExpandedImage: Path que apunta a la imagen que se mostrar cuando el contenido est maximizado.

ExpandDirection: podemos definir que el contenido se abra de arriba a abajo o de izquierda a derecha. En el primer caso asignaremos Vertical y en el segundo Horizontal.

AJAX y ASP.NET 63

Ejemplo

<asp:Label ID="Label1" runat="server" Text="Label" CssClass="CP"></asp:Label> <asp:Panel ID="Panel1" runat="server" Width="120px"> Este es el contenido que ser abierto o cerrado mediante el controlador, que se corresponde con el texto de arriba. ste a su vez describir el estado. </asp:Panel> <ajaxToolkit:CollapsiblePanelExtender ID="CollapsiblePanelExtender1" runat="server" TargetControlID="Panel1" CollapsedSize="0" ExpandedSize="300" Collapsed="True" ExpandControlID="Label1" CollapseControlID="Label1" TextLabelID="Label1" CollapsedText="Abrir contenido" ExpandedText="Cerrar contenido" ExpandDirection="Vertical"/> </ajaxToolkit:CollapsiblePanelExtender>

ConfirmButton
Con el ConfirmButton conseguimos una sencilla funcionalidad. Lo asignaremos a un Button, LinkButton o Hyperlink, de modo que cuando se haga clic sobre ste, el navegador nos muestre una ventana de confirmacin. En sta deberemos elegir s o no para que se ejecute o no el evento asociado al control en cuestin.

Propiedades
TargetControlID: ID del control al que aplicaremos el efecto el ConfirmButton. ConfirmText: texto que se mostrar al presionar sobre el control. Por ejemplo Realmente desea ejecutar?

Ejemplo

Mostraremos un botn que se ocupar de recargar la pgina. Cuando se nos muestre la ventana de confirmacin elegiremos si realmente deseamos recargarla o no. <asp:Button ID="Button1" runat="server" Text="Recargar pgina" /> <ajaxToolkit:ConfirmButtonExtender ID="ConfirmButtonExtender2" runat="server" TargetControlID="Button1" ConfirmText="Realmente desea recargar la pgina?" /> </ajaxToolkit:ConfirmButtonExtender>

DragPanel
El DragPanel sera el ejemplo perfecto de cmo conseguir una funcionalidad avanzada, que en javascript requerira decenas de lneas de programacin, con apenas dos lneas de cdigo y una mayor flexibilidad.

Se aplica a cualquier control Web (el ms habitual es el Panel) y le aade la funcionalidad de poder arrastrarlo a cualquier parte de la pantalla. Vamos a distinguir entre el controlador y el contenido, donde el controlador es sobre lo que deberemos hacer clic y arrastrar para mover el contenido.

AJAX y ASP.NET 64

Propiedades
TargetControlID: el ID del control correspondiente al contenido. DragHandleID: el ID del control correspondiente al controlador.

Ejemplo

<asp:Panel ID="Panel3" runat="server" Height="50px" Width="125px"> <asp:Panel ID="Panel1" runat="server" Width="125px" BackColor="Yellow" Font-Bold="true" BorderColor="black" BorderWidth="1"> Arrstrame </asp:Panel> <asp:Panel ID="Panel2" runat="server" Height="250px" Width="125px" BorderColor="black" BorderWidth="1"> Este es el contenido que vamos a poder arrastrar por toda la pantalla. </asp:Panel> </asp:Panel> <ajaxToolkit:DragPanelExtender ID="DragPanelExtender1" runat="server" DragHandleID="Panel1" TargetControlID="Panel3"> </ajaxToolkit:DragPanelExtender>

<script type="text/javascript"> // Pequeo script para una correcta compatibilidad con todos los navegadores. function setBodyHeightToContentHeight() { document.body.style.height = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight)+"px"; } setBodyHeightToContentHeight(); $addHandler(window, "resize", setBodyHeightToContentHeight); </script>

DropDown
Un sencillo control que le da un aspecto muy avanzado y profesional a nuestra pgina, as como resultar se muy til. Consiste en hacer aparentar un DropDown donde no lo hay. Por ejemplo, imaginemos que tenemos dos paneles y que al hacer click sobre uno queremos que aparezca el segundo panel del mismo modo que aparece el contenido de una lista desplegable (en la imagen lo veremos mejor.

Propiedades
TargetControlID: ID del control sobre el que aplicaremos los efectos. Normalmente ser un Panel, pero puede ser cualquier cosa. DropDownControlID: El Id del Panel que ser mostrado como una lista desplegable.

Ejemplos

<asp:Label ID="TextLabel" runat="server" Text="Ponte sobre m" Font-Names="Tahoma" FontSize="11px" Style="display: block; width: 300px; padding:2px; padding-right: 50px;" />

<asp:Panel ID="DropPanel" runat="server" Style="display:none;visibility:hidden; fontfamily:Tahoma; font-size: 11px; padding:5px;"> Aqu puede haber cualquier control: imgenes, MultiViews... lo que queris!!<br /> Por ejemplo, pongamos un Calendario: <br /> <br />

AJAX y ASP.NET 65

<asp:Calendar ID="Calendar1" runat="server" BackColor="White" BorderColor="#999999" CellPadding="4" DayNameFormat="Shortest" Font-Names="Verdana" Font-Size="8pt" ForeColor="Black" Height="180px" Width="200px"> <SelectedDayStyle BackColor="#666666" Font-Bold="True" ForeColor="White" /> <TodayDayStyle BackColor="#CCCCCC" ForeColor="Black" /> <SelectorStyle BackColor="#CCCCCC" /> <WeekendDayStyle BackColor="#FFFFCC" /> <OtherMonthDayStyle ForeColor="#808080" /> <NextPrevStyle VerticalAlign="Bottom" /> <DayHeaderStyle BackColor="#CCCCCC" Font-Bold="True" Font-Size="7pt" /> <TitleStyle BackColor="#999999" BorderColor="Black" Font-Bold="True" /> </asp:Calendar> <br /> Si pusiramos el calendarios sobre un UpdatePanel... podramos hacer maravillas ;) </asp:Panel> <ajaxToolkit:DropDownExtender runat="server" ID="DDE" TargetControlID="TextLabel" DropDownControlID="DropPanel" />

DropShadow
El DropShadow extiende al control Panel con dos caractersticas muy interesantes: - Aade una sombra, permitindonos definir tanto su profundidad como su oscuridad. - Crea un efecto de redondeado del Panel. Por consiguiente, conseguimos dos efectos muy profesionales de forma tremendamente sencilla.

Propiedades
TargetControlID: ID del Panel sobre el que aplicaremos los efectos. Width: profundidad en pixels de la sombra. Es un parmetro opcional que por defecto vale 5. Opacity: valor decimal en tre 0 y 1 que define la opacidad de la sombra, donde el 0 corresponde a transparencia total y 1.0 a completamente opaco. Tambin es opcional y su valor por defecto es 0.5. TrackPosition: lo pondremos a true si nuestro panel lo hemos definido con posicin absoluta o si va a poder ser movido. En caso contrario pondremos false (o no ponemos nada). Rounded: Si queremos un efecto de redondeado lo pondremos a true, sino, vale con ponerlo a false.

<asp:Panel ID="Panel1" runat="server" Width="125px" BackColor="Yellow" Font-Names="Arial"> <div style="padding:5px"> En este panel podemos poner lo que queramos. El efecto de sombreado + bordeado es muy agradable a la vista. </div> </asp:Panel> <ajaxToolkit:DropShadowExtender ID="DropShadowExtender1" runat="server" Opacity="1" Width="5" TargetControlID="Panel1" Rounded="true"> </ajaxToolkit:DropShadowExtender>

Ejemplo

AJAX y ASP.NET 66

FilteredTextBox
El FilteredTextBox extiende al TextBox de modo que podemos definir qu tipo de caracteres permitimos que escriba el usuario. Elegiremos entre estas configuraciones y sus mltiples combinaciones: - Numbers: todos los nmeros - LowercaseLetters: letras minsculas. - UppercaseLetters: letras maysculas. - Custom: los caracteres que definamos.

Propiedades
TargetControlID: ID del TextBox sobre el que vamos a actuar. FilterType: Tipo de filtro de entre los que hemos definido previamente. Los combinaremos separndolos en comas. ValidChars: slo se le har caso si hemos elegido a Custom como FilterType. Ser un string con los caracteres que consideraremos vlidos.

Ejemplo

En nuestro ejemplo vamos a permitir que en nuestro TextBox se escriban nicamente nmeros y los signos matemticos +, -, * y /. <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <ajaxToolkit:FilteredTextBoxExtender ID="FilteredTextBoxExtender1" runat="server" TargetControlID="TextBox1" FilterType="Numbers,Custom" ValidChars="+-*/" > </ajaxToolkit:FilteredTextBoxExtender>

HoverMenu
El HoverMenu es un extendedor aplicable a cualquier control Web. Vamos a distinguir entre el cuerpo y el popup, de modo que cuando el ratn pase sobre el control web cuerpo, el control web popup aparezca en el lugar en que hayamos especificado. Adems, cuando esto suceda, podemos aplicar una clase CSS al control web cuerpo, haciendo ver al usuario que es el causante de que aparezca el popup.

Propiedades

AJAX y ASP.NET 67

TargetControlID: ID del control identificado como cuerpo. PopupControlID: ID del control identificado como popup. HoverCssClass: clase CSS que se aplicar al cuerpo cuando pasemos el ratn sobre ste. PopupPostion: lugar donde aparecer el popup con respecto al cuerpo. Por defecto vale Left, y sus otros valores son Right, Bottom y Center. OffsetX/OffsetY: una vez definido el PopupPosition, podemos aadir o quitar pixels en horizontal o en vertical con respecto a su posicin relativa. PopDelay: la cantidad de milisegundos que pasarn entre que nos posemos sobre el cuerpo hasta que aparezca el popup. Por defecto son 100.

Ejemplo

En nuestro ejemplo, el cuerpo se corresponde con un botn y el popup con un Panel, de modo que cuando el usuario vaya a hacer clic sobre el botn, se muestre un mensaje (Podemos asignarle cualquier propiedad al Panel): <asp:Button ID="Button1" runat="server" Text="Haz clic" /> <asp:Panel ID="Panel1" runat="server" Height="50px" Width="125px" BackColor="Yellow" BorderWidth="1px" ScrollBars="Auto"> Si presionas sobre el botn, se recargar la pgina. </asp:Panel> <ajaxToolkit:HoverMenuExtender ID="HoverMenuExtender1" runat="server" PopupControlID="Panel1" TargetControlID="Button1" PopupPosition="Right" OffsetX="10"> </ajaxToolkit:HoverMenuExtender>

ModalPopup
El ModalPopup es otro ejemplo de potente funcionalidad en muy pocas lneas de cdigo. Con ste, conseguimos el efecto de mostrar contenido deshabilitando la interaccin con el resto de la pgina. Podemos emular el efecto del famoso window.open(...) de javascript sin necesidad de salir de la pgina en que estamos ni de abrir una nueva ventana del navegador. Imaginemos que el usuario presiona el botn Dime tu nombre y apellidos, de repente la pgina se oscurece y aparece en el centro un cuadro donde se pide el nombre y los apellidos... todo ello sin salir de la pgina en que estamos y sin poder hacer nada con el resto de elementos de sta. As pues, el usuario puede elegir entre cancelar -para volver donde estaba antes- y rellenar sus datos y presionar OK, activando una llamada a una funcin javascript que hayamos definido. Distinguiremos entre el activador, que en nuestro ejemplo es el botn Dime tu nombre y apellidos, y el popup, que en nuestro ejemplo se corresponde con el panel que nos mostrar el formulario de entrada de datos del usuario.

Propiedades

AJAX y ASP.NET 68

TargetControlID: ID del control activador. Tpicamente ser un Button o un LinkButton. PopupControlID: ID del control popup. Tpicamente ser un Panel. BackgroundCssClass: clase CSS que se aplicar al fondo de pantalla, por ejemplo para dar un efecto de oscuridad a los elementos sobre los que no vamos a poder interactuar. DropShadow: le daremos el valor de true si queremos que se aada un efecto de sombra a nuestro control popup. OkControlID: el ID del elemento que produce el efecto de OK de nuestro popup. OnOkScript: nombre del script que se activar cuando presionemos sobre OK. OkCancelID - The ID of the element that cancels the modal popup OmCancelScript - Script to run when the modal popup is dismissed with the CancelControlID

Ejemplo

En nuestro ejemplo, el activador ser un Button que mostrar una ventana emergente (popup). Desde sta actuaremos de forma diferente si presionamos sobre OK o sobre Cancel. En nuestro ejemplo hemos presionado OK <asp:Button ID="Button1" runat="server" Text="Abrir ventana emergente" /> <asp:Panel ID="Panel1" runat="server" Width="125px" BackColor="yellow"> Ventana emergente debida a la llamada del botn <br /> <asp:Button ID="Button2" runat="server" Text="OK" /> <asp:Button ID="Button3" runat="server" Text="Cancel" /> </asp:Panel> <ajaxToolkit:ModalPopupExtender ID="ModalPopupExtender1" runat="server" CancelControlID="Button3" OkControlID="Button2" OnCancelScript="Cancel()" OnOkScript="OK()" PopupControlID="Panel1" TargetControlID="Button1"> </ajaxToolkit:ModalPopupExtender> <script type="text/javascript"> function OK() { alert('Has apretado OK'); } function Cancel() { alert('Has apretado Cancel'); } </script>

AJAX y ASP.NET 69

NoBot
El NoBot es un potentsimo control que nos ayudar a luchar contra el spam. Su funcionalidad trata de emular a los Captcha, de modo que se trata de evitar que un robot haga varios postback en la Web. Recordemos que los Captcha suelen ser imgenes de caracteres distorsionados sobre los que un humano tiene que evaluar qu caracteres son e introducirlos. Por tanto, un Captcha es mucho ms seguro que un NoBot, pero el NoBot no requiere participacin humana alguna, por lo que se hace transparente al usuario y le evita molestias. As pues, podremos aplicar el NoBot sobre aplicaciones Web donde el Spam no sea un problema crtico, sino simplemente molesto.

Propiedades
OnGenerateChallengeAndResponse: mtodo de servidor opcional desde donde podemos implementar un trabajo especfico extra para ayudar al NoBot a detectar robots. Lo veremos mejor en el ejemplo. ResponseMinimumDelaySeconds: nmero de segundos por debajo de los cuales un postback se considerar invlido.

CutoffWindowSeconds: ventana de tiempo en segundos utilizada por el CutoffMaximumInstances. CutoffMaximumInstances: cantidad de PostBacks permitidos por una misma IP en la ventana de tiempo definida por CutoffWindowSeconds.

AJAX y ASP.NET 70

Ejemplo

Vamos a trabajar con el NoBot desde dos frentes. Por una parte no permitiremos que se hagan dos PostBacks en menos de 6 segundos (tiempo exagerado para hacer mejor la prueba. Por otro lado, mediante la funcin CustomChagellengeResponse, vamos a exigir que el navegador implemente el motor DOM, algo que s hacen todos los navegadores modernos, pero no es comn en Robots de Spam. La comprobacin de si se ha pasado el Test la hacemos en el manejador del evento Load de la pgina, indicando si procede- el motivo por el cual no se ha pasado la prueba. NoBot.aspx <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label> <br /> <asp:Button ID="Button1" runat="server" Text="Button" /> <ajaxToolkit:NoBot ID="NoBot1" runat="server" ResponseMinimumDelaySeconds="6" OnGenerateChallengeAndResponse="CustomChallengeResponse" /> NoBot.aspx.cs protected void Page_Load(object sender, EventArgs e) { if (IsPostBack) { AjaxControlToolkit.NoBotState estado; if (!NoBot1.IsValid(out estado)) Label1.Text = "Eres un robot: " + estado.ToString(); else Label1.Text = "No eres un robot ;)"; } } protected void CustomChallengeResponse(object sender, AjaxControlToolkit.NoBotEventArgs e) { // Implicamos al motor DOM del navegador, exigindole unos sencillos calculos sobre el rea de un Panel que nos inventamos Panel p = new Panel(); p.ID = "ParaMSCoder"; Random rand = new Random(); p.Width = rand.Next(300); p.Height = rand.Next(200); p.Style.Add(HtmlTextWriterStyle.Visibility, "hidden"); p.Style.Add(HtmlTextWriterStyle.Position, "absolute"); ((AjaxControlToolkit.NoBot)sender).Controls.Add(p); e.ChallengeScript = string.Format("var e = document.getElementById('{0}'); e.offsetWidth * e.offsetHeight;", p.ClientID);

e.RequiredResponse = (p.Width.Value * p.Height.Value).ToString(); }

AJAX y ASP.NET 71

NumericUpDown
NumericUpDown extiende al control Web TextBox habilitando unos botones que incrementan/decrementan el valor de ste. El incremento/decremento puede corresponder a: - El simple +1/-1 aritmtico. - Subir o bajar dentro de un listado de valores que le demos. - Llamar a un servicio Web o un mtodo de la pgina diferente segn si incrementamos o decrementamos. Podremos asignar botones para que hagan de incrementador/decrementador o dejar los que hay por defecto.

Propiedades
TargetControlID: ID del TextBox sobre el que vamos a actuar. Width: anchura combinada del TextBox y sus botones de arriba/abajo que vienen dados por defecto (mnimo 25). Si elegimos que otros botones hagan esa funcin, est propiedad se ignorar. RefValues: listado de valores sobre los que querremos ir subiendo y bajando. Los daremos en forma de string separado por punto y coma ;. TargetButtonDownID/TargetButtonUpID: ID de los botones que har la funcin de incrementar y decrementar. ServiceDownPath/ServiceUpPath: path del servicio Web al que llamaremos cuando se incremente o decremente. En caso de estar trabajando con mtodos de pgina no utilizaremos esta propiedad. ServiceDownMethod/ServiceUpMethod: mtodo que ser llamado para incrementar/decrementar el TextBox. Deber tener la forma: [WebMethod] public int NextValue(int current, string tag) {} Tag: se corresponde con el segundo parmetro del mtodo al que llamaramos, y lo podemos utilizar para distinguir qu elemento est llamando al mtodo.

Ejemplo

En nuestro sencillo ejemplo, vamos a viajar por los planetas del sistema solar, donde ya no incluiremos a nuestro querido Plutn. <asp:TextBox ID="TextBox1" runat="server" Text="Tierra" Width="120" style="textalign:center"></asp:TextBox> <cc1:NumericUpDownExtender ID="NumericUpDownExtender1" runat="server TargetControlID="TextBox1" Width="120" RefValues="Mercurio;Venus;Tierra;Marte;Jpiter;Saturno;Urano;Neptuno" ServiceDownMethod="" ServiceUpMethod="" TargetButtonDownID="" TargetButtonUpID=""> </cc1:NumericUpDownExtender>

PasswordStrength

AJAX y ASP.NET 72

El PasswordStrength es otro extendedor del TextBox. Con l podremos mostrar al usuario el nivel de fortaleza que tiene la contrasea que est escribiendo, en base a unos parmetros tpicos de fortaleza que definiremos nosotros: - Nmero total de caracteres. - Exigencia de signos. - Exigencia de combinar maysculas y minsculas. - Exigencia de nmeros. Podemos elegir y configurar los dos modos que tenemos de mostrar al usuario la fortaleza de su password: - Mediante texto 100% configurable. - Mediante una barra que se ir rellenando. Adems, podemos aadir la opcin de ayuda, donde explicar al usuario cmo debe ser su contrasea.

Propiedades
TargetControlID: ID del TextBox sobre el que vamos a trabajar. DisplayPosition: posicin relativa del indicador con respecto al TextBox. Puede tomar 6 valores: AboveLeft, AboveRight, BelowLeft, BelowRight, LeftSide, RightSide. StrengthIndicatorType: tipo de indicador: Text o BarIndicator. PreferredPasswordLength: longitud mnima que debera tener la contrasea. PrefixText: prefijo a mostrar cuando estemos mostrando el texto que describa la fortaleza de la contrasea. Tpicamente ser Fortaleza= . TextCssClass: clase CSS que se aplicar al texto que describe la fortaleza de la contrasea. MinimumNumericCharacters: cantidad mnima de caracteres numricos. MinimumSymbolCharacters: cantidad mnima de signos (ej.: $ ^ *) RequiresUpperAndLowerCaseCharacters: especificamos si exigimos la combinacin de maysculas y minsculas. TextStrengthDescriptions: listado de texto que se usar para describir la fortaleza de la contrasea. Ir ordenado de dbil a fuerte y separado por punto y coma ;. Tendr un mnimo de 2 textos y un mximo de 10. Por ejemplo: muy dbil;dbil;mejorable;buena;perfecta. CalculationWeightings: listado de 4 valores numricos separados por ;, donde la suma de ellos debe dar 100. Cada valor asigna un porcentaje de importancia a una caracterstica del password; por ejemplo 40;25;15;20 significa que el 40% del peso de fortaleza viene de la longitud de la contrasea, el 25% a la cantidad de nmeros, el 15% a maysculas/minsculas y el 20% a la cantidad de caracteres no alfanumricos. BarBorderCssClass: Clase CSS del borde de la barra indicadora. BarIndicatorCssClass: Clase CSS del interior de la barra indicadora. HelpStatusLabelID: ID de la Label que usaremos opcionalmente- para mostrar el texto de ayuda. HelpHandleCssClass: clase CSS del elemento que mostrar el texto de ayuda. HelpHandlePosition: posicin relativa del elemento de ayuda con respecto al TextBox. Puede tomar 6 valores: AboveLeft, AboveRight, BelowLeft, BelowRight, LeftSide, RightSide.

Ejemplo

AJAX y ASP.NET 73

Veamos qu fortaleza nos asigna este control: <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <cc1:PasswordStrength ID="PasswordStrength1" runat="server" DisplayPosition="rightside" MinimumNumericCharacters="2" MinimumSymbolCharacters="2" PreferredPasswordLength="13" PrefixText="Fortaleza: " RequiresUpperAndLowerCaseCharacters="true" StrengthIndicatorType="Text" TargetControlID="TextBox1" TextStrengthDescriptions="muy dbil; dbil; mejorable; buena; perfecta"> </cc1:PasswordStrength>

PopupCOntrol
El PopupControl se puede aplicar a cualquier control Web al que llamaremos cuerpo- y su funcionalidad consiste en mostrar una pequea ventana emergente con infomacin adicional. Esa ventana emergente a la que llamaremos popup- puede ser tambin cualquier control Web (tpicamente un panel) y dentro de l podemos ubicar cualquier cosa. Por ejemplo, imagnese un TextBox en el que cuando se pone el ratn sobre l, emerja un calendario sobre el que podamos elegir una fecha y en el momento la elijamos, sta se plasme en el TextBox.

Propiedades
TargetControlID: ID del control cuerpo. PopupControlID: ID del control popup. Position: posicin relativa en la que aparecer el popup con respecto al cuerpo. Sus valores

posibles sern: Left, Right, Top, Bottom, Center. CommitProperty: especifica la propiedad del control cuerpo que se modificar con el resultado del popup. Por ejemplo, en el caso de un TextBox, lo normal es que queramos modificar su value, aunque tambin podramos modificar su Width, su TextMode... Es opcional. CommitScript: funcin javascript que se ejecutar cuando hayamos dado el resultado del popup. OffsetX/OffsetY: distancia horizontal/vertical en pixels que aadiremos o quitaremos a la posicin relativa del popup con respecto del cuerpo.

AJAX y ASP.NET 74

Ejemplo

Aplicaremos el ejemplo propuesto en 3.15.1 PopUp.aspx Fecha: <asp:TextBox ID="TextBox1" runat="server" Width="80"></asp:TextBox> <asp:Panel ID="Panel1" runat="server" CssClass="popupControl"> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <center> <asp:Calendar ID="Calendar1" runat="server" BackColor="White" BorderColor="#999999" CellPadding="1" DayNameFormat="Shortest" Font-Names="Verdana" Font-Size="8pt" ForeColor="Black" Width="160px" OnSelectionChanged="Calendar1_SelectionChanged"> <SelectedDayStyle BackColor="#666666" Font-Bold="True" ForeColor="White" /> <TodayDayStyle BackColor="#CCCCCC" ForeColor="Black" /> <SelectorStyle BackColor="#CCCCCC" /> <WeekendDayStyle BackColor="#FFFFCC" /> <OtherMonthDayStyle ForeColor="#808080" /> <NextPrevStyle VerticalAlign="Bottom" /> <DayHeaderStyle BackColor="#CCCCCC" Font-Bold="True" Font-Size="7pt" /> <TitleStyle BackColor="#999999" BorderColor="Black" Font-Bold="True" /> </asp:Calendar> </center> </ContentTemplate> </asp:UpdatePanel> </asp:Panel> <ajaxToolkit:PopupControlExtender ID="PopupControlExtender1" runat="server" TargetControlID="TextBox1" PopupControlID="Panel1" Position="Bottom"> </ajaxToolkit:PopupControlExtender> PopupControl.aspx.cs protected void Calendar1_SelectionChanged(object sender, EventArgs e) { PopupControlExtender1.Commit(Calendar1.SelectedDate.ToShortDateString()); }

ResizableControl

AJAX y ASP.NET 75

El ResizableControl extiende cualquier control Web (por ejemplo un Panel o una imagen) confirindole la propiedad de redimensionamiento. Podemos, por ejemplo, coger un Panel con texto y redimensionarlo a nuestro gusto sin ms que cogerlo con el ratn. Adems, aade multitud de funcionalidades, como lanzamiento de eventos onresizing y onresize con los que podemos crear lgica compleja. Su estado se mantiene durante los postbacks y sus dimensiones se pueden acceder desde cliente (javascript) y desde servidor (ASP.NET). Tambin podemos limitar su anchura y altura mximas.

Propiedades
TargetControlID: ID del control Web que vamos a poder redimensionar. HandleCssClass: clase CSS de elemento que debemos coger para redimensionar. ResizableCssClass: clase CSS que se aplicar cuando estemos redimensionando. MinimumWidth/MinimumHeight: anchura/altura mnimas. MaximumWidth/MaximumHeight: anchura/altura mximas. OnClientResize: evento que se lanzar cuando el elemento haya sido redimensionado OnClientResizing: evento que se lanzar cuando el elemento est siendo redimensionado. HandleOffsetX/HandleOffsetY: offsets a aplicar sobre el elemento redimensionador.

<style> .handleText { width:16px; height:16px; background-image:url(images/HandleGrip.png); overflow:hidden; cursor:se-resize; } </style> <asp:Panel ID="Panel1" runat="server" Height="50px" Width="125px"> Elemento que se va a redimensionar </asp:Panel> <ajaxToolkit:ResizableControlExtender ID="ResizableControlExtender1" runat="server" MinimumWidth="50" MinimumHeight="20" MaximumWidth="250" MaximumHeight="125" HandleCssClass="handleText" TargetControlID="Panel1"> </ajaxToolkit:ResizableControlExtender>

Ejemplo

RoundedCorners
Aplica un redondeado de los bordes a cualquier control Web (habitualmente un Panel). Podemos elegir el radio de redondeo.

Propiedades

AJAX y ASP.NET 76

TargetControlID: ID del control Web sobre el que se aplicar el redondeo. Habitualmente es un Panel. Radius: radio de redondeo de las esquinas. Por defecto vale 5. Color: color de fondo del rea redondeada en las esquinas. Por defecto se coge el color de fondo del Panel al que pertenece.

Ejemplo

<asp:Panel ID="Panel1" runat="server" Width="125px" BackColor="#557755"> Este es el panel sobre el que se aplicar el bordeado. </asp:Panel> <ajaxToolkit:RoundedCornersExtender ID="RoundedCornersExtender1" runat="server" TargetControlID="Panel1" Radius="8"> </ajaxToolkit:RoundedCornersExtender>

Slider
El Slider es un extendedor del TextBox, de modo que al aplicarlo sobre l, se convierte en un deslizador (ver ejemplo). Sus funcionalidades son mltiples. Por ejemplo se puede sincronizar con un TextBox o una Label, de modo que se va mostrando el valor numrico que representa. Podemos elegir un valor mnimo y un valor mximo, as como permitir nmeros decimales. El movimiento del Slider puede ser contnuo o discreto (le marcaremos los pasos que debe dar). Adems, soporta postbacks e incluso lo podemos combinar con un UpdatePanel para viajar al servidor en modo AJAX.

Propiedades
Minimum: Valor inferior. Por defecto es 0. Maximum: Valor superior. Por defecto 100. Decimals: Cantidad de decimales. Por defecto no hay. Steps: Cuando queramos un deslizamiento discreto, marcaremos la cantidad de pasos. Value: Valor actual del deslizador. EnableHandleAnimation: Activa la animacin. HandleAnimationDuration: duracin en milisegundos de la animacin. RailCssClass: Asigna una clase CSS a la va sobre la que se mueve el deslizador. HandleCssClass: Asigna una clase CSS al deslizador.

HandleImageURL: opcionalmente podemos asignar una imagen al deslizador. Length: Longitud del deslizador. Por defecto se coger la longitud del TextBox que estamos extendiendo BoundControlID: ID del TextBox o Label en el que estamos mostrando el valor del deslizador. RaiseChangeOnlyOnMouseUp: Si se activa, lanza el evento change cuando se suelta el botn izquierdo del ratn.

AJAX y ASP.NET 77

Ejemplo

Mostramos lo fcil que es crear un Slider. <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox> <ajaxToolkit:SliderExtender ID="SliderExtender1" runat="server" TargetControlID="TextBox1" BoundControlID="TextBox2" />

TextBoxWatermark
El TextBoxWatemark extiende, de nuevo, al control TextBox. Su funcionalidad consiste en que aparezca un texto (de una clase CSS especfica) en el TextBox cuando este no haya sido rellenado por el usuari, de modo que cuando hagamos clic sobre ste, ese texto desaparezca, y si nos vamos del textbox sin haber escrito nada, el texto vuelve a aparecer. Su finalidad habitual es la de mostrar al usuario cierta informacin antes de rellenar el TextBox.

Propiedades
TargetControlID: ID del TextBox que vamos a extender. WatermarkText: Texto que se mostrar cuando no haya nada escrito en el TextBox. WatermarkCssClass: la clase CSS que se aplicar al TextBox cuando no haya nada escrito.

Ejemplo

Vamos a pedir el nombre de usuario y contrasea. En la primera imagen vemos cmo quedarn los cuadros de texto nada ms cargarse la pgina; en la segunda imagen hemos hecho click sobre el primer TextBox y de inmediato se ha borrado el texto Nombre de usuario para dejarnos escribir lo que queramos. <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <br /> <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox> <ajaxToolkit:TextBoxWatermarkExtender ID="TextBoxWatermarkExtender1" runat="server" TargetControlID="TextBox1" WatermarkText="Nombre de usuario" /> <ajaxToolkit:TextBoxWatermarkExtender ID="TextBoxWatermarkExtender2" runat="server" TargetControlID="TextBox2" WatermarkText="Contrasea" />

AJAX y ASP.NET 78

ToggleButtn
El ToggleButton extiende al control CheckBox. Su nica funcionalidad consiste en sustituir por imgenes el estado de un CheckBox. Es decir, si el CheckBox est checked mostrar una imagen especfica, y su est unchecked mostrar otra.

Propiedades
TargetControlID: ID del CheckBox que extenderemos. CheckedImageUrl: URL de la imagen a mostrar cuando el CheckBox est Checked. UncheckedImageUrl: URL de la imagen a mostrar cuando el CheckBox est UnChecked. DisabledCheckedImageUrl: URL de la imagen a mostrar cuando el CheckBox est deshabilitado y en estedo de Checked. DisabledUncheckedImageUrl: URL de la imagen a mostrar cuando el CheckBox est deshabilitado y en estedo de UnChecked. CheckedImageAlternateText: texto alternativo de la imagen definida en CheckedImageUrl. UncheckedImageAlternateText: texto alternativo de la imagen definida en UnCheckedImageUrl. ImageHeight/ImageWidth: Altura/Anchura de la imagen que se va a mostrar.

Ejemplo

<asp:CheckBox ID="CheckBox1" Checked="true" Text="Mi CheckBox" runat="server"/> <br> <ajaxToolkit:ToggleButtonExtender ID="ToggleButtonExtender1" runat="server" TargetControlID="CheckBox1" ="No seleccionado" />

ValidatorCallout
El ValidatorCallout es un extendedor de cualquier tipo de validador (RequiredFieldValidator, RangeValidator, CustomValidator...), con el que conseguimos una vista mucho ms amable de los tpicos validadores. No tenemos que aplicar los validadores como lo hemos hecho hasta ahora (ver http://www.subgurim.net/articulos/asp-net-general-articulo48.aspx), pero con el detalle de aadirles el atributo Display=None y asignarles el ValidatorCallout.

Propiedades
TargetControlID: ID del Validador que se est extendiendo. Width: Anchura del Callout HighlightCssClass: Opcionalmente se puede asignar una clase CSS sobre el Callout.

WarningIconImageUrl: Url del icono que muestra la alerta. Si no se especifica se muestra el que viene por defecto. CloseImageUrl: Imagen que produce el cierre del Callout

AJAX y ASP.NET 79

Ejemplo

Un ejemplo vale ms que mil palabras, y en casos como el Callout mucho ms: <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" Display="None" ErrorMessage='Mensaje de error donde podemos aadir todo tipo de HTML, por ejemplo una <a href="http://www.es-asp.net">Url cualquiera</a>.' ControlToValidate="TextBox1"></asp:RequiredFieldValidator> <br /> <asp:Button ID="Button1" runat="server" Text="Button" /> <ajaxToolkit:ValidatorCalloutExtender runat="Server" ID="ValidatorCalloutExtender1" TargetControlID="RequiredFieldValidator1" Width="350px" />

You might also like