Sie sind auf Seite 1von 356

INCLUYE NOVEDADES DE LA VERSiN 3.

DESCUBRA UN NUEVO NIVEL EN EL DESARROLLO DE APLICACIONES PARA INTERNET


SILVERUGHT PARA DISEADORES Y DESARROLLADORES MICROSOFT EXPRESSION BLEND 2 Y MICROSOFT VISUAL STUDIO 2008 UNQ, WCF y SERVICIOS WEB CON C# CREACiN DE ANIMACIONES Y TCNICAS DE ESCRITURA PARA DISPOSITIVOS TCTILES INTERACCiN CON JAVASCRIPT, HTML, XML y CSS
1 ,j
, "' j

por MATAS IACONO


\

I I '

,1"

r,

'

II

\l

'\ j

"

APROVECHE AL MXIMO SU POTENCIAL ILIMITADO

CONCTESE CON LOS MEJORES

LIBROS DE COMPUTACIN
usershop.redusers.com

DESCUBRA EL POTENCIAL DE WINDOWS VISTA


MANUALES USERS I 384 pginas I ISBN 978-987-1347-40-7

APRENDA A PROGRAMAR CON EL LENGUAJE MS POTENTE


DESARROLLADORES I 400 pginas I ISBN 978-987-1347-76-6

MANEJE LAS HERRAMIENTAS DE VISTA COMO UN EXPERTO


MANUALES USERS I 352 pginas I ISBN 978-987-663-007-8

DESARROLLE APLICACIONES PARA WINDOWS Y LA WEB


MANUALES .CODE I 368 pginas I ISBN 978-987-1347-32-2

DESCUBRA UN NUEVO NIVEL EN EL DESARROLLO DE APLICACIONES PARA INTERNET

TTULO: AUTOR: COLECCIN: FORMATO: PGINAS:

SILVERLIGHT Matas Iacono Manuales USERS 17 x 24 cm 352

Copyright MMIX. Es una publicacin de Gradi S.A. Hecho el depsito que marca la ley 11723. Todos los derechos reservados. No se permite la reproduccin parcial o total, el almacenamiento, el alquiler, la transmisin o la transformacin de este libro, en cualquier forma o por cualquier medio, sea electrnico o mecnico, mediante fotocopias, digitalizacin u otros mtodos, sin el permiso previo y escrito del editor. Su infraccin est penada por las leyes 11723 y 25446. La editorial no asume responsabilidad alguna por cualquier consecuencia derivada de la fabricacin, funcionamiento y/o utilizacin de los servicios y productos que se describen y/o analizan. Todas las marcas mencionadas en este libro son propiedad exclusiva de sus respectivos dueos. Impreso en Argentina. Libro de edicin argentina. Primera impresin realizada en Sevagraf, Costa Rica 5226, Grand Bourg, Malvinas Argentinas, Pcia. de Buenos Aires en octubre de MMIX. ISBN 978-987-663-010-8

Iacono, Matas Silverlight. - 1a ed. - Banfield - Lomas de Zamora : Gradi, 2009. 352 p. ; 24x17 cm. - (Manual users; 175) ISBN 978-987-663-010-8 1. Informtica. I. Ttulo CDD 005.3

PRELIMINARES

Matas Iacono
Ingeniero de sistemas, Microsoft Most Valuable Professional en ASP.net, Orador Regional para INETA Latam, Scrum Master certificado y Microsoft Certified Technology Specialist. Cuenta con ms de quince aos de experiencia en el desarrollo de software con distintas tecnologas y metodologas. Ha dictado cerca de cincuenta conferencias tcnicas en distintos pases latinoamericanos, as como escrito y publicado artculos en numerosas publicaciones internacionales. Ha trabajado para empresas extranjeras de gran envergadura. En la actualidad, se desempea como ingeniero de software para Motorola Argentina y es profesor en la Universidad Tecnolgica Nacional de Crdoba.

Agradecimientos
Agradezco a todos los amigos que me brindaron su apoyo y sus opiniones sobre lo escrito. A Miguel Saez, de Microsoft, por haberme facilitado material y a Lucas Ontivero, de Motorola Argentina, por su crtica aguda, que me ayud con el contenido propuesto en el libro.

Dedicatoria
A mi familia, por quedarse a mi lado largos fines de semana mientras conclua este libro.

Prlogo

PRLOGO
Si hay algo a lo que le debemos la actual difusin de la tecnologa informtica, tanto dentro del hogar como de las oficinas, es a la continua evolucin de las interfaces grficas de usuarios (GUI). Gracias a ellas, personas de todas las edades y profesiones, en todo el mundo, pueden interactuar con equipos de computacin para fines tan diversos como entretenerse, obtener informacin, realizar clculos y comunicarse, entre un sinnmero de otras posibilidades. Es seguro que tanto la constante innovacin en el desarrollo de las interfaces grficas como la aparicin de Internet han sido los catalizadores para uno de los ms fabulosos cambios en la manera en que las personas, alrededor del globo, se relacionan mediante el uso de la tecnologa. Mientras que la Web seguir siendo el mbito de comunicacin del futuro, es de esperar que los requerimientos de interactividad entre mquinas y humanos se vuelvan an ms sofisticados y exigentes. Ante esto, Microsoft desarroll Silverlight, una nueva apuesta para el desarrollo de elementos de grficos de interaccin con los usuarios orientados a la Web. En este aspecto es, justamente, en el que esta obra hace un gran aporte, al presentar Silverlight 2.0 de una manera amena, clara y completa. En ella, se abarcan no slo los pormenores tcnicos de la tecnologa, sino que, adems, el autor se ha esmerado en brindar al lector un cmulo de conocimientos que slo podra obtenerse mediante la experiencia, todo esto reflejado en tips, datos tiles, recomendaciones, curiosidades, advertencias y todos los consejos que el lector reconocer como invaluables a la hora de adentrarse en esta apasionante tecnologa. Por ltimo, quisiera agradecer a Matas Iacono por este maravilloso trabajo que ha sido una gua segura en el aprendizaje de Silverlight y, con cuya lectura y estudio, me he sentido guiado y acompaado siempre.

Lucas Ontivero Ingeniero de software, Motorola Argentina

PRELIMINARES

EL LIBRO DE UN VISTAZO
En esta obra se vern los conceptos principales para dominar Silverlight, la tecnologa de Microsoft orientada al desarrollo de contenido dinmico y animaciones para la Web. El contenido est dirigido a desarrolladores con conocimiento de Microsoft .Net Framework, C# como lenguaje principal, y que dominen algunos conceptos de JavaScript y HTML.

Captulo 1
INTRODUCCIN A SILVERLIGHT 2 Para conocer Silverlight desde sus comienzos, en este captulo describiremos su arquitectura. Hablaremos de las diferencias entre aplicaciones tradicionales y las nuevas aplicaciones visuales, y conoceremos la lista de herramientas necesarias para poder desarrollar aplicaciones Silverlight.

tipos de proyectos disponibles desde este entorno de desarrollo.

Captulo 4
XAML AL EXTREMO Cada uno de los controles y componentes proporcionados por Silverlight, su funcionalidad, eventos, mtodos y funciones, sern vistos en este captulo. Cada uno de estos elementos ser descripto con profundidad, generando cdigo de ejemplo por cada uno de ellos. Este captulo representa una excelente gua de referencia sobre todos los componentes disponibles en Silverlight.

Captulo 2
MICROSOFT EXPRESSION BLEND 2 En este captulo nos enfocaremos en Microsoft Expression Blend 2 como herramienta de desarrollo para Silverlight, orientada a diseadores visuales y a diagramadores de aplicaciones. Daremos un paseo por la interfaz de Microsoft Expression Blend 2 y crearemos nuestra primera aplicacin Silverlight. Este captulo ayudar a los diseadores y desarrolladores a entender cada uno de estos mundos.

Captulo 5
LUZ, CMARA, ACCIN Gran parte de las prestaciones otorgadas por Silverlight incluyen la posibilidad de mover objetos dentro de nuestra aplicacin. En este captulo veremos cmo manipular esta caracterstica, ya que se explicarn los distintos modelos disponibles para animaciones y transformaciones dentro de las aplicaciones Silverlight.

Captulo 3
EL MEJOR TRABAJO, CON LA MEJOR HERRAMIENTA Luego de enfocarnos en el diseador visual, centraremos la atencin de este captulo en el desarrollador. Para esto, veremos qu posibilidades nos ofrece Microsoft Visual Studio 2008 para desarrollar aplicaciones Silverlight, los controles y componentes propuestos, su interfaz visual y los diferentes 6

Captulo 6
CERRAR EL CRCULO Silverlight tambin otorga mucho potencial con el manejo de imgenes, video y sonido. En este captulo hablaremos de ciertas caractersticas relacionadas con actividades

El libro de un vistazo

como consumir videos, mostrar imgenes o tocar sonidos dentro de las aplicaciones. Tambin hablaremos de Deep Zoom y sus caractersticas, as como del dibujo a mano alzada con InkPresenter.

Apndice A
SILVERLIGHT FUERA DE WINDOWS Gracias a MoonLight, Silverlight puede salir de Windows y trabajar en sistemas operativos basados en Linux y Unix. Hablaremos del proyecto MoonLight, sus caractersticas, limitaciones y el futuro de Silverlight como tecnologa fuera de su ambiente nativo. Adems, se presentan algunas herramientas gratuitas y de cdigo libre que nos ayudarn en el desarrollo, tanto para Windows como para Linux.

Captulo 7
INTERCONEXIN Este captulo ofrece funcionalidades altamente valiosas. Crearemos un juego desde cdigo C# y un lector de RSS, usaremos almacenamiento aislado para guardar informacin en el cliente, crearemos aplicaciones para subir archivos al servidor y culminaremos con la implementacin de la ltima tecnologa de interoperabilidad propuesta por Microsoft al conectar Silverlight con Windows Communication Foundation.

Apndice B
SILVERLIGHT 3, LA NUEVA GENERACIN Daremos un vistazo al producto recientemente lanzado por Microsoft. Silverlight 3 trae consigo valiosas mejoras al modelo ya planteado, las que enumeraremos para ganar conocimiento adicional por sobre lo ya aprendido durante todo el libro.

Captulo 8
EL NAVEGADOR Y SU DOMINIO Silverlight se ejecuta dentro de una pgina HTML manejada por el navegador web. Por tal motivo, posee gran potencial de interaccin con el cliente. En este captulo veremos cmo Silverlight puede manipular HTML as como intercambiar informacin con JavaScript. Adems, conoceremos cmo JavaScript es capaz de consumir servicios generados desde Silverlight.

Servicios al lector
En esta ltima seccin, encontraremos un ndice que nos ayudar a buscar de forma rpida los trminos ms importantes de esta obra. Adems, veremos un listado de sitios de inters para ampliar nuestros conocimientos y mantenernos al tanto de las ltimas novedades en la materia.

INFORMACIN COMPLEMENTARIA

A lo largo de este manual encontrar una serie de recuadros que le brindarn informacin complementaria: curiosidades, trucos, ideas y consejos sobre los temas tratados. Cada recuadro est identificado con uno de los siguientes iconos:

_`

CURIOSIDADES E IDEAS

ATENCIN

RRR

DATOS TILES Y NOVEDADES

SITIOS WEB

Contenido

CONTENIDO
Sobre el autor Prlogo El libro de un vistazo Informacin complementaria Introduccin 4 5 6 7 12

Captulo 3
EL MEJOR TRABAJO, CON LA MEJOR HERRAMIENTA Silverlight para desarrolladores Puesta a punto de Visual Studio 2008 Silverlight 2 con Visual Studio Crear la primera aplicacin con Visual Studio 2008 63 56 56 59

Captulo 1
INTRODUCCIN A SILVERLIGHT 2 Iniciarse en el mundo de Silverlight 2 Navegar hacia el mundo de Silverlight 2 La experiencia de usuario y la portabilidad Arquitectura de Silverlight 2 Microsoft .Net Framework Interfaz de usuario y presentacin El cdigo XAML Herramientas de desarrollo para Silverlight 2 Resumen Actividades 24 27 28 16 19 20 21 22 14 14

Interoperabilidad con Expression Blend 2 Resumen Actividades 76 79 80

Captulo 2
MICROSOFT EXPRESSION BLEND 2 Un paseo por Expression Blend 2 Silverlight 2 con Expression Blend 2 Unir los extremos Un recorrido por Expression Blend 2 Explorador de soluciones Pgina inicial de Silverlight 2 La pgina App.xaml El entorno de Expression Blend 2 La barra de herramientas Crear nuestra primera aplicacin con Expression Blend 2 Resumen Actividades 48 53 54 30 30 32 37 38 39 40 43 46

Captulo 4
XAML AL EXTREMO El lenguaje XAML Qu es XAML? Declaracin de objetos Controles y componentes Controles contenedores y agrupadores Control Grid Control GridSplitter Control Canvas Control StackPanel Control ScrollViewer Control Border 82 82 82 83 84 84 89 92 95 98 101

Controles de interaccin con el usuario 103

PRELIMINARES

Control Button Control CheckBox Control RadioButton Control HyperlinkButton Control Image Control ComboBox Control ListBox Control TextBlock Control TextBox Control PasswordBox Control DataGrid Control Calendar Control DatePicker Control ProgressBar Control Slider Resumen Actividades

103 106 110 113 114 117 124 126 127 130 132 139 147 148 152 153 154

ColorAnimation Animaciones y transformaciones Estilos y plantillas Estilos Plantillas Resumen Actividades

173 175 178 178 182 185 186

Captulo 6
CERRAR EL CRCULO MediaElement Ejecutar sonidos Video Elementos con video embebido Marcadores de video Deep Zoom Crear el primer Deep Zoom Incluir Deep Zoom en Silverlight 188 188 194 195 196 199 200 203 208 212 215 217 219 220

Captulo 5
LUZ, CMARA, ACCIN Mover objetos Transformaciones Transformacin de traslacin Transformacin de rotacin Transformacin escalar Transformacin de distorsin Aplicar todas las transformaciones Animaciones DoubleAnimation 156 158 159 161 165 167 168 170 171

Dibujar con InkPresenter Dibujar en forma manual Dibujar sobre otros elementos InkPresenter y reas de dibujo Resumen Actividades

Captulo 7
INTERCONEXIN Ampliar las funcionalidades Silverlight desde C# 222 222

10

Contenido

WebClient Enviar informacin Almacenamiento aislado Implementar el almacenamiento aislado Capacidad de almacenamiento Almacenar configuraciones OpenFileDialog Manejo de hilos El concepto de hilos Temporizador Personalizar los hilos Hilos y eventos Consumir servicios desde Silverlight Crear un servicio WCF Manipular datos Enlazado de datos LinQ Resumen Actividades

230 233 239 240 245 247 251 255 256 257 259 261 263 270 275 276 283 287 288

Cookies Modificar CSS Silverlight 2 y JavaScript Llamar funciones Objetos Silverlight para JavaScript Resumen Actividades

316 320 323 325 327 347 348

Apndice A
SILVERLIGHT FUERA DE WINDOWS Proyecto Moonlight Sistemas operativos Versiones de Moonlight Herramientas de desarrollo Problemas conocidos 330 330 331 331 333

Captulo 8
EL NAVEGADOR Y SU DOMINIO

Apndice B
SILVERLIGHT 3, LA NUEVA GENERACIN Silverlight 3 Nuevos controles Efectos en tres dimensiones Uso de Pixel Shader Conectar tecnologas Silverlight 2 y el HTML HtmlDocument y HtmlElement HtmlPage HtmlWindow 290 290 292 301 307 Fuera del navegador 336 336 337 338 339

Servicios al lector
ndice temtico Sitios web recomendados 342 345

11

PRELIMINARES

INTRODUCCIN
Este libro est orientado a desarrolladores de software, y diseadores visuales y grficos que deseen expandir su rea de conocimiento de desarrollo hacia el ambiente web. Un lector con nociones iniciales podr ver, durante los captulos, una evolucin que le dar la oportunidad de aprender sin necesidad de saberes previos sobre la tecnologa propuesta, Silverlight, mientras que aquel lector con experiencia podr encontrar en estas pginas una gua fundamental para aprender, con agilidad, conceptos sobre esta tecnologa de Microsoft. Sin embargo, es necesario, para ambos lectores, contar con conocimientos medios de desarrollo utilizando Microsoft C#, as como las tcnica primordiales del funcionamiento y ejecucin de la Web. Los temas propuestos en el libro fueron seleccionados para cubrir la mayor superficie de conceptos sobre Silverlight 2, presentados de una manera progresiva de tal forma que el lector se sienta cmodo con su evolucin y que aprenda a cada paso que da. Desde la recomendacin y el uso de las herramientas ideales para el desarrollo bajo esta tecnologa, tanto para diseadores como para desarrolladores, generamos ejemplos prcticos en cada captulo, que abarcan desde HTML hasta C#, as como la aplicacin de ASP.net y el uso de JavaScript. Silverlight es un modelo en ebullicin. En el momento de lanzarse la versin 1, sus caractersticas eran limitadas; pero, al poco tiempo, Microsoft mejor la tecnologa y sac a relucir la segunda versin de Silverlight, versin de la que se ocupa este libro. Pero esta efervescencia, este cambio constante junto a la bsqueda de un mejor producto y de una tecnologa superior, hicieron que, durante el tiempo de escritura de este libro, Microsoft sacara la siguiente versin de Silverlight. En este momento, ya contamos con la versin 3 de Silverlight como una versin funcional y finalizada, por lo que incluimos un apartado, al final del libro, para introducir al lector en algunas de las nuevas funcionalidades provistas por Silverlight 3. De esta forma, con este texto, el lector no slo aprender sobre Silverlight, sino que tendr un bono extra al final, que le servir de rampa de lanzamiento para abordar de lleno la nueva versin y permanecer siempre actualizado.

12

Silverlight

Captulo

Introduccin a Silverlight 2
En este primer captulo veremos el porqu de Silverlight 2, al mismo tiempo que hablaremos de problemas comunes en el desarrollo de software desde la ptica de las interfaces grficas, los diseadores y programadores, as como las limitaciones de las herramientas usadas por cada uno.
Iniciarse en el mundo de Silverlight 2 Navegar hacia el mundo de Silverlight 2 La experiencia de usuario y la portabilidad Arquitectura de Silverlight 2 Microsoft .Net Framework Interfaz de usuario y presentacin El cdigo XAML Herramientas de desarrollo para Silverlight 2 Resumen Actividades 14 14 16 19 20 21 22 24 27 28

SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com

1. INTRODUCCIN A SILVERLIGHT 2

INICIARSE EN EL MUNDO DE SILVERLIGHT 2


Muchos cambios se han producido en el desarrollo web desde sus inicios. Se han sucedido mejoras sustanciales hasta la llegada de la Web 2.0 y, sin embargo, se siguen buscando mejores formas y herramientas para trabajar en este fascinante mundo. Recorramos esos aos de evolucin hasta la actualidad, cuando una de estas herramientas ve la luz para traer una solucin a nuevas necesidades. Veamos, en este captulo, los componentes clave de Silverlight 2: las herramientas de desarrollo y diseo, su arquitectura y los elementos principales que le dan vida.

Navegar hacia el mundo de Silverlight 2


Desde los inicios de la Web, sta ha ido evolucionando, mutando y creciendo. Esta evolucin se inici con la simple transferencia de texto, pas por las imgenes y la captura de datos del usuario por parte del sistema, hasta llegar al manejo de contenido personalizado. ste se genera para el usuario y por l, simulando casi el mismo comportamiento de aplicaciones desarrolladas para sistemas de escritorio. Los cambios radicales en las tasas de transferencias de datos, as como en las capacidades de los equipos que servan esta informacin, tambin acompaaron dichos acontecimientos. Por supuesto, esta evolucin no slo fue de capacidades de hardware y prestaciones hacia el usuario. Al mismo tiempo, estuvo acompaada por software, lenguajes de programacin y herramientas de desarrollo que, en conjunto, ayudaran a amortiguar la curva de complejidad sobre las necesidades crecientes que tenan los sistemas. En definitiva, existan mayores requerimientos por parte de los usuarios y de los sistemas, por lo que la implementacin en lneas de cdigo y la puesta en marcha de los servicios necesitaron de herramientas que hicieran ms simple este trabajo. En la actualidad, el desarrollo web est ms pujante que nunca. Adems, con el advenimiento de teoras (y prcticas) como el Cloud Computing o servicios de Internet totalmente dinmicos para correos electrnicos, confeccin de documentos, redes sociales e interconexin de servicios, entre otros, debemos entender que la Web seguir creciendo y mejorando durante mucho ms tiempo. Esto nos llevar de vuelta a la idea antes tratada: mayor complejidad, mejoramiento en las herramientas y el soporte. Esta mejora en las herramientas que brindan soporte tanto al desarrollador como al diseador se hace cada vez ms necesaria y es mucho ms requeridas por aquellos que se ven involucrados en el desarrollo web. Debido a que desarrollar para la Web no se restringe al uso de una tecnologa nica y definitiva, el desarrollador web se ve en la necesidad imperativa de adquirir dominio y conocimientos sobre decenas de tecnologas y lenguajes de programacin, como XML, HTML, CSS, JavaScript, ActionScript, Lingo, PHP, C# y Java, entre muchas otras que forman el conjunto de la Web. Y es aqu donde se hace
14

Iniciarse en el mundo de Silverlight 2

visible Silverlight. Este software forma parte de dicho crecimiento y sirve como solucin, ya que plantea una mejor forma de desarrollar contenido dinmico para la Web. Esto sucede no slo en lo visual, sino tambin como herramienta de desarrollo basado en tecnologas comunes ya conocidas. No debemos equivocarnos al pensar que Silverlight constituye la estrategia de Microsoft para competir con el ya popular Flash, ex de Macromedia, y ahora de Adobe. Por el contrario, Silverlight representa una oportunidad de reutilizar el conocimiento ya adquirido sobre cdigo basado en Microsoft.Net Framework, un modelo que soporta no slo lenguajes desarrollados y mantenidos por esta empresa, sino que cuenta, por el contrario, con el soporte de compaas creadoras de lenguajes tan populares como Borland C# Builder y Delphi, tambin de Borland. De esta forma, Silverlight trae consigo la posibilidad de enriquecer la experiencia visual en el cliente web, trabajando en cualquiera de los navegadores de Internet ms conocidos. Puede interactuar y ser modificado por lenguajes como JavaScript, extendiendo el concepto de HTML dinmico y A.J.A.X. (Asynchronous JavaScript and XML o, en castellano, JavaScript asncrono y XML). Tambin puede consumir servicios web o cualquier elemento con la capacidad de retornar XML, al mismo tiempo que puede ser programado o desarrollado mediante aquel lenguaje que usamos todos los das para nuestros desarrollos, o con el que nos sintamos ms cmodos para generar las lneas de cdigo que darn vida a nuestra aplicacin.

VB

C++

C#

J#

...

Common Language Specification ASP .NET Web Forms Web Services Mobile Internet Toolkit ADO .NET y XML Librera de clases base Common Language Runtime Sistema Operativo

Windows Forms

Figura 1. Microsoft .Net Framework es el nexo entre el sistema operativo y nuestro cdigo. Nos ofrece una plataforma de ejecucin, libreras de cdigo, acceso a datos y soporte para diferentes lenguajes.
15

Visual Studio .NET

1. INTRODUCCIN A SILVERLIGHT 2

La experiencia de usuario y la portabilidad


Antes de la aparicin de Microsoft .Net Framework, construir una aplicacin de software requera diferentes habilidades y dependa del ambiente en el cual se desarrollara esta aplicacin. As, si las aplicaciones necesitaban desarrollarse para ser usadas bajo Windows, stas requeran que su diseo visual se creara de manera especial para este modelo. Al mismo tiempo, debera contemplar las limitaciones que el lenguaje de programacin trajera consigo. El diseo, entonces, quedaba encapsulado dentro del cdigo del lenguaje seleccionado, siendo casi imposible su implementacin en otro lenguaje o en una nueva versin del mismo. Pensemos que, si una aplicacin deba ser migrada a una nueva versin del lenguaje o, por necesidades de negocio, deba ser implementada en otro lenguaje, toda la interfaz visual deba ser reescrita e implementada. A lo anterior debamos sumar que, si exista un cambio de ambiente, es decir, si movamos el desarrollo a un dispositivo mvil o a la Web, no slo la interfaz deba ser reescrita, sino que tambin deba cambiar la lgica radicada en el cdigo. Esto no slo acarrea reinversin de tiempo y dinero, sino que, adems, la interfaz (y tal vez la lgica de negocio) nunca quedara del todo igual, castigando la experiencia del usuario que se haba acostumbrado a una herramienta ya construida e implementada. Con la primera versin del .Net Framework, Microsoft hace el intento inicial de generar portabilidad entre ambientes y lenguajes, separando la interfaz grfica del lenguaje de programacin y proveyendo componentes comunes para que los ambientes similares puedan reutilizar las interfaces ya creadas. Gracias a esto, tenamos aplicaciones creadas para Windows, que tambin funcionaban en dispositivos mviles, aunque an quedaba trabajo por hacer en cuanto a desarrollo web y Windows, ya que estos dos ambientes seguan siendo incompatibles. Con la versin 3.0 de Microsoft .Net Framework, se introdujo un nuevo enfoque por medio de un esquema XML para la confeccin y manipulacin de interfaces de usuarios: ya no aparecan los tpicos botones y cajas de texto rgidas comunes en cualquier aplicacin de escritorio. Este esquema, llamado XAML (eXtensive Application Markup Language, o en castellano, Lenguaje Extensible de Formato para Aplicaciones) por sus siglas en ingls, le permiti al desarrollador crear otro tipo de aplicaciones a nivel visual. XAML fue explotado por WPF (Windows Presentation Foundation), pero muy rpido se entendi que XAML tena mucho futuro por delante.

QU ES SILVERLIGHT?

La experiencia demuestra que la primera reaccin por parte de los desarrolladores al ver Silverlight es asociarlo en forma directa con la competencia de Adobe Flash. Silverlight persigue objetivos similares, pero se separa de Adobe Flash en ciertos aspectos tcnicos, como lenguajes de programacin y arquitectura.

16

Iniciarse en el mundo de Silverlight 2

CardSpace

WPF

Microsoft .NET Framework Versin 2.0

WF

WCF

Figura 2. CardSpace, WCF, WPF y WF (Workflow Foundation) se agregan como parte de Framework 3 sobre la versin 2 de Framework.

Silverlight 2 usa, para la representacin visual de sus elementos, XAML. Las mismas etiquetas que, como decamos antes, tambin son soportadas por aplicaciones de escritorio construidas con WPF. Esto genera una ventaja significativa sobre la creacin de aplicaciones y la adaptacin del usuario a nuevas tecnologas. Pensemos que, al tener un componente comn como XAML para la representacin visual de elementos de la interfaz grfica, el esfuerzo aplicado para la creacin de uno de estos componentes puede ser reutilizado y explotado en otros ambientes, no slo en aquel para el cual Silverlight fue ideado. Pensemos entonces en una aplicacin de escritorio, con cientos de usuarios que la usan durante meses o aos y, de un momento a otro, se encuentran usando la misma aplicacin, pero dentro de un navegador web, con los mismos botones, el mismo contenido visual e igual comportamiento. Uno de los lados ms rugosos en la implementacin de un sistema est atado a la adopcin de ste por parte del usuario, y es en los cambios de plataformas y ambientes donde se producen las discordias. Aqu es necesario

_`

MICROSOFT .NET Y LENGUAJES

Microsoft .Net Framework no slo soporta los lenguajes de programacin propuestos por Microsoft. Tambin podemos encontrar otros como Boo, Icc, Clarion#, Cobol, Corba, Eiffel, Fortran, Lisp, PHP, Perl y ms. Esto puede resultar en especial interesante, ya que no necesitamos aprender un nuevo lenguaje para desarrollar en Microsoft .Net Framework.

17

1. INTRODUCCIN A SILVERLIGHT 2

invertir mayor esfuerzo para que esta nueva idea sea aceptada. Por tal motivo, nos har falta toda la ayuda posible al momento de hacer este cambio. En la Web, las aplicaciones tienen ms representatividad y, por ende, su atractivo y su facilidad de uso necesitan potenciarse. Esta mejora es llevada a cabo por la implementacin de soluciones que conjugan JavaScript y XML, dando como producto la pieza conocida como A.J.A.X., donde bien podemos encontrar cientos de modelos listos para ser implementados. Pero el desarrollo sigue enfocndose en la manipulacin del HTML que, sin desmerecer sus posibilidades, siempre llegar a un techo mximo, relacionado con las capacidades del mismo modelo HTML. En comparacin con el modelo de aplicaciones de escritorio, la interactividad ofrecida por este ltimo es muy superior a la que presenta HTML, y es aqu donde Silverlight, una vez ms, explota lo mejor de estos dos mundos y lo lleva en forma directa al mbito de aquel que pierde en comparacin: el del HTML.
Aplicaciones de escritorio

Navegadores web

CSS/HTML

XAML

JavaScript/AJAX ASP.net

Framework .Net

Figura 3. Silverlight se nutre de cada una de las principales caractersticas de los dos mundos, generando una mejor experiencia de usuario e independencia en plataformas.

RRR

VERSIONES DE MICROSOFT .NET FRAMEWORK

Es importante entender las diferencias entre las versiones de Microsoft .Net Framework. Slo a partir de la versin 3, se incorpora el uso de XAML, as como WPF, pero el ncleo de este Framework se mantiene idntico al de la versin 2. Al desarrollar para cualquiera de estas nuevas plataformas, deberemos elegir una versin de Framework 3 o superior.

18

Iniciarse en el mundo de Silverlight 2

Como observamos en la Figura 3, Silverlight toma lo mejor de los dos mundos. Por un lado, los controles y componentes verstiles propuestos por el desarrollo de escritorio y, por el otro, la portabilidad entre plataformas y la rapidez de la actualizacin de aplicaciones a miles de usuarios al mismo tiempo que otorga Internet. Esta versatilidad y portabilidad entre plataformas, tanto de escritorio como web, no sera posible sin un lenguaje comn de representacin de controles. XAML es el lenguaje que nos dar esta posibilidad no slo para el desarrollo, sino que tambin brinda la oportunidad de aumentar la versatilidad de las interfaces, poder llevar el comportamiento de las aplicaciones de escritorio a la Web, posibilitar la adopcin por parte del usuario final de manera independiente del sistema, mediante el aumento de la calidad y de la velocidad en el desarrollo, y otros puntos ganados con la utilizacin de XAML y Silverlight.

Arquitectura de Silverlight 2
Al comienzo de nuestro recorrido, nombramos algunas de las caractersticas de Silverlight que, al mismo tiempo, definen su planteo arquitectnico. Dijimos que Silverlight est enfocado a la Web y que es ejecutado por el navegador web. Esto se consigue gracias a un plugin o aditivo que har las veces de gestor o intrprete. Este componente ronda los 5 megabytes, lo que constituye una suma muy pequea en relacin con su potencia. En la actualidad, es soportado por los principales navegadores de Internet como Internet Explorer, FireFox y Safari, as como los sistemas operativos Windows (con base en Windows XP con Service Pack 2 y hasta Windows 7), Mac OS X 10+ y Linux. Pero Silverlight, aunque hemos hecho hincapi en la gestin de interfaces de usuario, no slo es un lienzo donde podemos crear animaciones vectoriales, sino, muy por el contrario, consiste en una plataforma liviana de desarrollo con soporte para SOA (Service Oriented Architecture o, en castellano, Arquitectura Orientada a Servicios), redes, manejo de datos, y ms. Como observamos en la Figura 4, Silverlight va mucho ms all y nos entrega, por sobre todas las cosas, acceso a las ltimas tecnologas y patrones de desarrollo de software. Podemos separar y enumerar las diferentes caractersticas sobre la base de su rea de trabajo, como veremos a continuacin.

_`

LA DIFCIL ADOPCIN POR PARTE DE LOS USUARIOS

Por lo general, es difcil lograr que un usuario adopte una nueva aplicacin cuando est acostumbrado a la que usa desde hace aos. Este problema de adopcin se ve potenciado en quienes nunca usaron una computadora. Pero, si podemos reproducir en el ordenador lo que el usuario est acostumbrado a utilizar en la vida real, la adopcin ser casi transparente.

19

1. INTRODUCCIN A SILVERLIGHT 2

.NET para Silverlight Data LINQ XLINQ XML WPF Controls Data Binding Layout Editing WCF REST RSS/ATOM SOAP POX JSON Librera para Microsoft AJAX

DLR Iron Python Iron Ruby Jscript

BCC Generics Collections Cryptography Threading Motor JavaScript

Motor de ejecucin CLR

XAML Centro de interfaz grfica Vector Animation Text Images

Perifricos Keyboard Mouse Ink

DRM Media

Multimedia VC1 WMA MP3 Centro de presentacin Manejo de navegador Integrado con la red Integrado con DOM Servicio de aplicaciones Instalador

Figura 4. En este diagrama podemos observar la arquitectura soporte completa de Silverlight 2.

Microsoft .Net Framework


Con respecto a las lneas de cdigo y de clases ya implementadas para ser usadas por el desarrollador de cdigo, el Framework disponible cubre todas las reas necesarias para interactuar con datos y hasta con lenguajes propios de la Web.
20

Iniciarse en el mundo de Silverlight 2

LinQ y XLinQ: soporte especializado para llevar a cabo el manejo de colecciones de objetos, acceso a datos y XML. Con LinQ podremos crear consultas integradas con el lenguaje de programacin. WCF (Windows Communication Foundation): plataforma de comunicacin para acceso a servicios web, servicios remotos y peticiones HTTP, entre otros. Librera de clases base: acceso a las libreras de clases de Microsoft .Net Framework, que nos ofrece soporte para el manejo de cadenas de texto, expresiones regulares, serializacin de datos, manejo de internacionalizacin de aplicaciones y ms. CLR (Common Language Runtime): motor de Microsoft .Net que se encarga del manejo de la memoria y dems puntos de contacto con el sistema operativo. DLR (Dynamic Language Runtime, en castellano Lenguajes Dinmicos): soporte para lenguajes de programacin como JavaScript, Iron Phyton e Iron Ruby. Almacenamiento aislado: permite generar sectores de almacenamiento de archivos e informacin de manera aislada y para usuarios especficos.

Interfaz de usuario y presentacin


Silverlight tambin presenta una gran cantidad de funcionalidad en cuanto a su presentacin visual y puede manejar sonidos, imgenes y videos, as como una serie de controles y componentes listos para usar. Video y sonido: inclusin de soporte de formatos de video y sonido comunes como MP3 y WMA. Incluye capacidades de streaming. Imgenes: capacidad de despliegue de imgenes tanto vectoriales como mapas de bits en sus formatos ms comunes, texto y animaciones. Enlazado de datos: capacidad de enlazado de fuentes de datos automtica que facilita el despliegue de la informacin desde diferentes fuentes de datos. Controles: set de controles listos para usar que brindan la posibilidad de crear nuestro propio set de controles y de reusarlos en diferentes aplicaciones. XAML: implementacin de eXtensible Application Markup Language para la confeccin de las interfaces. stas son creadas sobre la base de XML. Como pudimos ver hasta aqu, Silverlight no es un simple visualizador de animaciones, sino un avanzado complemento de desarrollo que hace uso de las principales tecnologas Microsoft y que permite desenvolvernos con soltura al momento de desarrollar aplicaciones sobre ste. Silverlight, entonces, nos ofrece la potencia de los lenguajes de programacin utilizados, por lo general, en el desarrollo de aplicaciones de escritorio y web, adems, de su posibilidad de interaccin con bases de datos y servicios remotos. Tambin, nos brinda la elegancia de sus vistosas interfaces visuales, que pueden interactuar con lenguajes cliente, tales como JavaScript, enmarcado en un navegador web, sin estar atado a un sistema operativo ni a un navegador especfico.
21

1. INTRODUCCIN A SILVERLIGHT 2

Figura 5. En la imagen, observamos los controles visuales listos para usar y su apariencia por defecto.

El cdigo XAML
Ya hemos nombrado a XAML como uno de los componentes fundamentales de Silverlight, pero veamos un poco ms en profundidad de qu se trata exactamente. XAML es un lenguaje declarativo, formado por etiquetas descriptivas para cada uno de los componentes que Silverlight pueda representar. XAML basa el concepto descriptivo en el conocido modelo de XML. Gracias a esta cualidad (base de XML), entender la estructura de XAML resulta simple e intuitivo. Veamos a continuacin un ejemplo de elementos XML simples:

RRR

PROGRAMACIN PROFESIONAL

Debido a que Silverlight puede ser desarrollado con los principales lenguajes de programacin soportados por Microsoft .Net Framework, ste brinda pleno soporte para la programacin orientada a objetos y puede absorber todos los beneficios inherentes a este modelo de programacin.

22

Iniciarse en el mundo de Silverlight 2

<Contenedor> <Elemento Atributo=Valor> Contenido del Elemento </Elemento> </Contenedor>

Etiquetas o tags descriptivas dentro de caracteres < y >. Cada elemento es iniciado con un nombre especfico y siempre deberemos sealar su cierre utilizando el mismo nombre ms los caracteres </, lo que especificar la finalizacin del tag. En el ejemplo, tambin podemos notar cmo un elemento puede contener otros elementos, as como atributos descriptivos y valores dentro del mismo nodo. XAML sigue este mismo patrn:
<Canvas Width=300 Height=300 Background=Brown> <TextBlock x:Name=Texto Text=Hola Mundo!></TextBlock> </Canvas>

El ejemplo en XAML nos demuestra que la estructura es similar al del que hemos usado para XML, con la salvedad de que las etiquetas o tags ya se encuentran definidas y asociadas a los elementos visuales que representan. En el ejemplo, colocamos un contenedor que tendr un tamao en ancho y en alto de 300 pixeles, y color de fondo azul. Dentro de este contenedor, encontramos otro control utilizado para la visualizacin de textos, que mostrar la frase Hola Mundo! en pantalla.

Figura 6. Resultado de nuestra primera prueba con XAML y Silverlight.


23

1. INTRODUCCIN A SILVERLIGHT 2

El ejemplo nos sirve, al mismo tiempo, para mostrar otros atributos importantes dentro del mundo de XAML y de Silverlight. Tanto el elemento Canvas como TextBlock son controles preestablecidos por el entorno de Silverlight. Canvas es utilizado para definir un elemento contenedor de otros componentes, y TextBlock nos da la posibilidad de mostrar texto en pantalla en forma de bloques. La combinacin de estos elementos produce lo que aparece en la Figura 6, pero el concepto va ms all porque muestra cmo, anidando elementos, podemos conseguir diferentes efectos visuales. As, es posible mezclar un control del tipo botn con un control utilizado para mostrar imgenes o videos y obtener como resultado un botn en cuyo fondo se reproduce un video. Por ltimo, el atributo x:Name es el que le otorga, al control, la capacidad de tener un nombre nico, descriptivo, que podr ser usado por el lenguaje de programacin que elijamos para darle funcionalidad a la interfaz visual. Con este atributo, podremos cambiar el texto representado al principio en tiempo de ejecucin, sobre la base de la reaccin de un evento por parte del usuario o por parte del flujo de nuestra aplicacin. A medida que avancemos en el libro, nos introduciremos dentro de XAML; tambin en los diferentes componentes y controles disponibles por parte del entorno de desarrollo y libreras de objetos.

Herramientas de desarrollo para Silverlight 2


Si tenemos en cuenta que una de las principales cualidades de Silverlight es el potenciamiento visual en interfaces de usuario, sera muy interesante contar con herramientas para su correcto diseo y diagramacin. As, de manera sencilla, nos guiaran en la confeccin de los elementos XAML, su estructura, controles anidados, enlazado a fuentes de datos, entre otros. Microsoft nos provee de dos herramientas principales, cada una de ellas enfocada a cubrir una de las ramas involucradas en la generacin de elementos Silverlight. Por un lado, para desarrolladores de software, la herramienta por excelencia es Microsoft Visual Studio en su versin 2008. Aunque la nueva versin de esta herramienta puede obtenerse con facilidad (Visual Studio 10), la que hemos nombrado es suficiente para emprender nuestra labor. Microsoft Visual Studio 2008 resultar ideal debido a su soporte de Microsoft .Net Framework 3.5, herramienta que trae consigo una serie de plantillas para Silverlight 2.

RRR

XAML Y XML

Gracias a la extensibilidad de XML como lenguaje de etiquetas es que XAML genera un nuevo subconjunto de estas etiquetas para la representacin de controles en el entorno de Silverlight. As lo hace flexible en la creacin de los elementos, fcil de entender y portable entre ambientes.

24

Iniciarse en el mundo de Silverlight 2

Figura 7. Visual Studio 2008 otorga pleno soporte para Silverlight 2 mediante plantillas como las que observamos en la imagen.

De cualquier manera, tendremos que instalar, adems de la herramienta mencionada, el Service Pack 1 para sta. La instalacin del Service Pack 1, junto con la de las herramientas de desarrollo de Silverlight 2, incluirn en Visual Studio 2008 las plantillas de la Figura 7. Debido a que la versin 2 de Silverlight vio la luz despus que la herramienta de desarrollo, este procedimiento resulta la nica forma de poder ver los asistentes y dems componentes dentro de la mencionada herramienta. Adems de las plantillas que acelerarn el desarrollo, podremos encontrar una serie de controles y componentes para su uso inmediato que, si bien, como veremos ms adelante, es posible construirlos por nuestra cuenta desde cero, toda la lgica de funcionalidad ya se encuentra contenida y probada en ellos. Esto nos ahorra tiempo de trabajo al no tener que desarrollar algo ya existente. Componentes como botones, calendarios y cajas de texto son slo algunos de los que encontraremos dentro del abanico de posibilidades. Como vemos en la Figura 8, Visual Studio 2008 nos presenta una lista completa de controles listos para usar que, como ya dijimos, tienen toda la lgica que necesitarn impresa en el mismo componente, y, adems, est pronta para usar.

DESCARGA DE SILVERLIGHT 2 TOOLS PARA VISUAL STUDIO 2008


Adems del Service Pack 1 para Visual Studio 2008, tambin deberamos contar con el conjunto de herramientas de Silverlight. stas pueden ser descargadas desde la direccin www.microsoft.com/downloads, ingresando Silverlight 2 tools for Visual Studio 2008 como criterio de bsqueda.

25

1. INTRODUCCIN A SILVERLIGHT 2

Figura 8. Grillas, cajas de texto y listas desplegables son slo algunos de los controles listos para usar incluidos en Visual Studio 2008.

Por otro lado, tambin existe una herramienta para diseadores grficos que no cuenten con experiencia en el desarrollo de software. Con una interfaz similar a la de herramientas para manejo fotogrfico, Microsoft Expression Blend 2 le permite al diseador grfico, y por qu no al desarrollador, construir XAML de manera rpida y amigable, como toda herramienta WYSIWYG (What you see is what you get o en castellano Lo que ves es lo que obtienes) por sus siglas en ingls. Esto quiere decir que, al trabajar con Microsoft Expression Blend 2, el diseo que planteemos ser igual al resultado final en el momento de ejecucin de la aplicacin de Silverlight. Deberemos usar Microsoft Expression Blend 2 si estamos habituados a la creacin de imgenes vectoriales o si slo buscamos acelerar el desarrollo de componentes Silverlight. Veremos ms a fondo las cualidades de Microsoft Expression Blend 2 a lo largo de los captulos, con suficiente detalle como para poder utilizarlo con cierta seguridad. Por ltimo, cabe mencionar que Microsoft Visual Studio 2008 y Microsoft Expression Blend 2 se compenetran de tal forma que, por lo comn, nos veremos creando cdigo en la primera herramienta, abriendo y editando el mismo proyecto en la segunda, para terminar con algunos retoques artsticos o acelerar el enlazado de datos en nuestro trabajo. En la Figura 9, podemos observar cmo un proyecto creado en Visual Studio 2008 puede ser abierto y manipulado en forma directa con Microsoft Expression Blend 2. Debido al mismo motivo citado en el caso de Visual Studio 2008, es necesario instalar un conjunto de herramientas en Microsoft Expression Blend 2 para contar con plantillas que den soporte a Silverlight 2. En este caso, el Service Pack 1 para Microsoft Expression Blend 2 nos otorgar la prestacin.
26

Iniciarse en el mundo de Silverlight 2

Figura 9. Microsoft Expression Blend 2 trabajando sobre una solucin creada en Microsoft Visual Studio 2008.

A lo largo del libro haremos referencia a estas dos herramientas, que sern usadas para los distintos ejemplos que plantearemos. Por tal motivo, es recomendable contar con las herramientas instaladas en nuestro equipo antes de continuar con los siguientes captulos. Es posible tambin realizar los ejemplos con las versiones gratuitas de Visual Studio 2008 (Visual Studio 2008 Express), aunque no podemos garantizar que los ejemplos de interfaz y otros aspectos concuerden con lo que los usuarios de estas versiones vern en sus equipos.

RESUMEN
Silverlight puede ser una herramienta extremadamente potente con soporte basado en Microsoft .Net Framework, que nos otorga la posibilidad de desarrollar en el lenguaje y la forma que mejor nos convenga. Desde la versin 1 de Silverlight hasta la actual, ha habido mejoras notables, con mayor funcionalidad y prestaciones tanto para el desarrollador como para el diseador visual. El usuario final se ve beneficiado al tener que descargar un plugin de tamao pequeo y que trabaja en casi todos los navegadores y sistemas operativos de la actualidad.

27

 ACTIVIDADES
PREGUNTAS TERICAS
1 En qu modelo se basa el cdigo XAML para representar los elementos de la interfaz? 2 Subconjunto de qu otro modelo de desarrollo visual para Windows podramos considerar a Silverlight? 3 Qu versin de Microsoft .Net Framework necesitamos, como mnimo, para trabajar con Silverlight 2.0? 3 Para conocer ms sobre desarrollo con 4 Qu sistemas operativos y navegadores web soportan la ejecucin de Silverlight 2.0? 5 Qu herramienta resulta ideal para desarrolladores, que les permita potenciar el desarrollo de aplicaciones Silverlight 2.0? 6 Los diseadores visuales cuentan con alguna herramienta de software que los ayude a crear contenido para Silverlight 2.0? 7 Es necesario instalar algn aditamento en la herramienta de desarrollo? 8 Silverlight 2.0 provee algn conjunto de componentes listos para usar? 9 Por qu es importante crear interfaces atractivas e intuitivas en las aplicaciones? 10 Cmo se llama el modelo de desarrollo para la Web que conjuga el uso de XML y JavaScript? Microsoft .Net, tome el curso gratuito del Desarrollador 5 Estrellas desde el sitio web de Microsoft. Este curso ayuda a entender trminos utilizados en este libro. La URL es www.mslatam.com/latam/msdn/ comunidad/dce2005. 4 Instale Microsoft Expression Blend 2 y djelo listo para trabajar en el siguiente captulo. 5 Una vez instalados Visual Studio 2008 y Microsoft Expression Blend 2, ingrese en www.silverlight.net, el sitio oficial de Silverlight, descargue los ejemplos y analcelos. Esto ayuda a entender con mayor facilidad esta tecnologa. 2 Para introducirse mejor en el mundo de Silverlight, intente ampliar el ejemplo propuesto en este captulo, modificando el tipo de fuente y el color de fondo de la aplicacin creada.

EJERCICIOS PRCTICOS
1 Dirjase al sitio web de la W3C (www. w3.org/XML) para aprender ms sobre XML.

28

Silverlight

Captulo

Microsoft Expression Blend 2


Cules son las herramientas disponibles para desarrollar aplicaciones Silverlight? Cmo podemos aumentar nuestra productividad a la hora de escribir XAML? stas son algunas de las preguntas que abordaremos en este captulo.
Un paseo por Expression Blend 2 Silverlight 2 con Expression Blend 2 Unir los extremos Un recorrido por Expression Blend 2 Explorador de soluciones Pgina inicial de Silverlight 2 La pgina App.xaml El entorno de Expression Blend 2 La barra de herramientas Crear nuestra primera aplicacin con Expression Blend 2 Resumen Actividades

30 30 32 37 38 39 40 43 46

SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com

48 53 54

2. MICROSOFT EXPRESSION BLEND 2

UN PASEO POR EXPRESSION BLEND 2


En el captulo anterior, nos introdujimos en el mundo de Silverlight 2. Vimos algunas de sus caractersticas, los elementos que lo componen y las principales herramientas de desarrollo usadas para la creacin de aplicaciones y componentes de Silverlight. Una de estas herramientas, Microsoft Expression Blend 2, es usada por los diseadores visuales y por los desarrolladores como un suplemento para los detalles visuales avanzados. En este captulo, ahondaremos en el uso de esta herramienta y su interaccin con Silverlight 2, cmo crear animaciones as como tambin elementos compuestos, para finalizar con la creacin de nuestra primera aplicacin Silverlight 2. Este contenido est dirigido, en especial, a diseadores visuales que quieran incursionar en el uso de Expression Blend 2 como herramienta de diseo para software y a desarrolladores de software que necesiten modificar, de manera rpida, interfaces visuales basadas en XAML.

Silverlight 2 con Expression Blend 2


Desde los inicios de su desarrollo, este software siempre se enfoc, de manera prioritaria, en las lneas de cdigo y en la solucin del problema propuesto. Esto sucede ya que, justamente, fueron el cdigo y el problema por corregir los que motivaron la creacin de soluciones de software, que provean una respuesta programtica a la dificultad planteada. Este enfoque, el de la solucin del problema, caus que en el desarrollo de software primara la capacidad y la calidad de resolucin de un problema por encima del enfoque interactivo entre la aplicacin y el ejecutor de ese programa. As, dentro de la historia del software y las computadoras, por carencias o por el enfoque antes citado, el trabajo se haca mediante tarjetas perforadas, las cuales se apilaban en grandes cajas y que posean, en s mismas, la resolucin de una de las partes que solucionaba el todo del problema. Sin ninguna duda, este sistema era manejado slo por el desarrollador de este software primario y no por alguien ajeno a la informtica de la poca. Desde ese momento de la historia y hasta la actualidad, se produjeron cambios en la manera en que el usuario interactuaba entonces e interacta ahora con esta pieza de software. Sin

_`

LA EVOLUCIN DE LAS INTERFACES

A pesar de ms de 40 aos de evolucin en la ingeniera de software, slo en la actualidad se pone especial nfasis en las interfaces visuales y en cmo stas pueden ser parte de la solucin del problema al que el usuario se debe enfrentar a diario. As, vemos aparecer nuevas tecnologas multitctiles en sistemas operativos, o de captura de movimientos en consolas de juegos.

30

Un paseo por Expression Blend 2

embargo, ste seguira encontrndose una y otra vez ante una herramienta que, aunque en esencia cubriera sus necesidades funcionales y resolviera el dominio del problema planteado, no abarcara los conceptos de usabilidad, ergonoma visual o interactividad entre el hombre y la mquina.

Figura 1. En el Mix 2009 realizado por Microsoft, uno de los temas por tratar fue la creacin de interfaces grficas.

Despus de algunas dcadas marcadas por este comportamiento de parte de la ingeniera de software y de aquellos que la han practicado, de alguna forma, el usuario termin acostumbrndose a la idea de obtener aplicaciones o piezas de software que aparecen, como grandes hitos visuales y pantallas monocromticas. Esto sucede, incluso, en pleno auge de las tarjetas aceleradoras de video con capacidades visuales que diez aos atrs se reservaban slo a inmensos ordenadores destinados a la produccin de efectos cinematogrficos. Muy pocos desarrolladores de software contemporneos, incluidas las empresas, contemplan como parte de sus desarrollos la inclusin de esta temtica. Slo con la llegada de la Web, algunos de ellos adicionaron esto como una necesidad comercial, pero, en muy pocos casos, como una realidad para brindar un mejor producto que, adems de solucionar un

CONSULTEMOS A UN DISEADOR

Es importante incluir en los proyectos de desarrollo de software a un diseador grfico que cuente con experiencia en interfaces de usuario. No debemos desestimar este punto en nuestros desarrollos. El xito de nuestro producto no est marcado slo por las lneas de cdigo, la usabilidad es un aspecto muy importante.

31

2. MICROSOFT EXPRESSION BLEND 2

problema, resulte optimizado en lo que a interactividad con el usuario se refiere. Por supuesto, la implantacin de este concepto dentro del desarrollo de software acarre ciertos problemas que han tenido que ser resueltos por fuerza bruta ms que por inteligencia, debido a que la solucin planteada, la de incorporar mejoras visuales e interactivas, requiere de la presencia de otras ciencias. Esas ciencias estn alejadas del desarrollo de software, por lo que el problema resulta bastante claro al tener que unir, de alguna forma, extremos que hablan idiomas diferentes.

Unir los extremos


En la actualidad, el mayor impedimento en la creacin de aplicaciones visuales y el trabajo realizado por los expertos en esta materia es causado por las herramientas que stos utilizan. Cuando en un proyecto de software es necesaria la intervencin de diseadores grficos especializados en experiencia de usuario, stos plasman su trabajo en herramientas ms ligadas a las doctrinas del diseo grfico y las artes visuales que a las del desarrollo de software. Entonces, el problema recae en que tanto el diseador como el desarrollador hablan idiomas diferentes: los primeros se refieren a colores, movimiento, disposicin de elementos y formas, entre otros aspectos, mientras que los segundos necesitan saber qu mostrar y cmo se realizar el cdigo que contenga la lgica. Al mismo tiempo, los diseadores suelen desconocer las limitaciones de las plataformas donde sern creados los productos de software y tienden a generar elementos visuales extremadamente atractivos, pero con costos elevados en su implementacin por parte del desarrollador. Al final y sin ser lo ltimo, el producto resultante del diseador ser un conjunto de imgenes o un esquema que mostrar lo pretendido de manera visual para la aplicacin de software, y le deja al desarrollador la tarea de volver a armar esto dentro de las lneas de cdigo, quien no lo conseguir con exactitud al compararlo con lo propuesto en un principio por el diseador. Y es aqu donde han surgido herramientas que traducen, de alguna forma, esto que el diseador piensa y plasma en algo que el desarrollador pueda usar. As, es posible encontrar herramientas muy potentes como Adobe Fireworks donde, por medio del modelo visual creado por el diseador, el desarrollador obtiene un conjunto de imgenes y cdigo HTML. A pesar de eso, este tipo de herramientas acarrea un problema, ya que se enfocan en el diseador y no en el desarrollador, creando cdigo HTML que, basado en el dibujo propuesto, generan HTML poco til para su implementacin, como podemos ver a continuacin. El siguiente es el resultado HTML generado para la Figura 2.
<tr> <td><img src=images/spacer.gif width=103 height=1 border=0alt= /></td>

32

Un paseo por Expression Blend 2

<td> [...41 lneas eliminadas ...] <td colspan=2><img name=Untitled1_r4_c1 src=images/Untitled1_r4_c1.gif width=112 height=60 border=0 id=Untitled1_r4_c1 alt= /></td> <td><img src=images/spacer.gif width=1 height=60 border=0 alt= /></td> </tr>

Y, si bien este cdigo puede ayudar, resulta imposible de usar para el desarrollador, por lo que ste se ver forzado a reescribir partes o su totalidad para poder obtener cdigo que le sea til. Para esto utilizar slo cdigo HTML, debido a que a ste se le pueden agregar cuestiones programticas a diferencia del anterior.
<span>Filtro de bsqueda</span> <br> <select> <option></option> <option></option> <option></option> </select>

Figura 2. A la derecha podemos ver lo que consigui el desarrollador como resultado del concepto ideado por el diseador.
33

2. MICROSOFT EXPRESSION BLEND 2

El problema es claro: estas herramientas hacen las veces de traductores, pero no de generadores. Traducen lo que el diseador quiso decir a algo que el desarrollador pueda entender, pero, en este proceso de traduccin, las herramientas no traducen funcionalidad, por lo que el desarrollador no la obtendr y deber retraducirla por su cuenta. La diferencia sustancial sobre este concepto por parte de Expression Blend 2 reside en que no es un traductor, sino un generador de funcionalidad, con la caracterstica de que para el diseador la herramienta se comportar como cualquier otra herramienta de las que est acostumbrado a usar. Sin embargo, a medida que diagrama y disea los contenidos visuales, sta generar funcionalidad lista para ser implementada por el desarrollador de software, como podemos observar en el siguiente cdigo:
<Grid x:Name=LayoutRoot Background=White> <TextBlock Height=23 HorizontalAlignment=Left Margin=96,32,0,0 VerticalAlignment=Top Width=174 Text=Filtro de bsqueda TextWrapping=Wrap FontFamily=Aharoni FontSize=18/> <ComboBox Height=42 HorizontalAlignment=Left Margin=96,59,0,0 Style={StaticResource ComboBoxStyle1} VerticalAlignment=Top Width=160 OpacityMask={x:Null}> <ComboBox.Foreground> <LinearGradientBrush EndPoint=0.5,1 StartPoint=0.5,0> <GradientStop Color=#FFF36767/> <GradientStop Color=#FFFFFFFF Offset=1/> </LinearGradientBrush> </ComboBox.Foreground> <ComboBox.Background> <LinearGradientBrush EndPoint=0.5,1 StartPoint=0.5,0> <GradientStop Color=#FFC07070/> <GradientStop Color=#FF0F0000 Offset=1/> </LinearGradientBrush>

_`

OPTIMIZACIN DE LA INTERFAZ

Existen especializaciones en el desarrollo de software que se enfocan en la optimizacin de las interfaces visuales, llegando al punto de calcular la cantidad de clics que deber hacer un usuario para conseguir realizar una accin determinada. La implementacin de estas tcnicas produce mayor aceptacin de los productos por parte de los usuarios.

34

Un paseo por Expression Blend 2

</ComboBox.Background> </ComboBox> </Grid>

El diseador ver, en lugar del cdigo anterior, un modelo como el que se muestra en la figura que aparece a continuacin:

Figura 3. Una lista desplegable creada con Expression Blend 2, que generar cdigo XAML listo para ser usado por el desarrollador.

Como el desarrollador obtiene cdigo que se adapta a sus necesidades, puede enfocarse directamente en la solucin del problema. A modo de ejemplo, en las siguientes lneas de cdigo vemos cmo el desarrollador agrega algunas lneas de cdigo C# en la clase asociada al cdigo XAML para generar funcionalidad sobre el producto del diseador:
public partial class Page : UserControl { public Page() { // Required to initialize variables InitializeComponent(); this.ComboBox.Items.Add(Item 1); this.ComboBox.Items.Add(Item 2);

35

2. MICROSOFT EXPRESSION BLEND 2

this.ComboBox.Items.Add(Item 3); } }

El resultado de esta implementacin de cdigo podemos verlo a continuacin:

Figura 4. Como observamos en esta imagen, el resultado propuesto por el diseador y la implementacin del desarrollador son idnticas.

Microsoft Expression Blend 2, entonces, sirve de nexo entre los dos elementos involucrados en el desarrollo, tanto para diseadores como para desarrolladores. De esta manera se logra que los productos resultantes en ambos casos sean compatibles entre s, para que ninguno de los profesionales involucrados tenga la necesidad de salir de su mbito natural de trabajo. El resultado final ser, entonces, que el diseador obtendr en la pieza de software el comportamiento y la apariencia visual, tal como los haba ideado, mientras que el desarrollador no se ver forzado a intentar traducir estas ideas a elementos programticos y se dedicar exclusivamente a la funcionalidad y a la resolucin del problema.

RRR

PROTOTIPO DEL PRODUCTO

Contar con un diseo visual de la aplicacin de manera temprana no slo sincronizar a los miembros del equipo de desarrollo, ya que todos tendrn una idea general del producto final, sino que puede servir de disparador de retroalimentacin por parte del cliente al ver con antelacin la idea del producto terminado.

36

Un paseo por Expression Blend 2

Un recorrido por Expression Blend 2


Al iniciar Expression Blend 2 o al crear un nuevo proyecto con l, podemos elegir entre cuatro tipos diferentes. Tenemos dos proyectos especficos para Silverlight y sus diferentes versiones, pero tambin podemos disear y trabajar con proyectos Windows Presentation Foundation (WPF). Aplicacin WPF: este tipo de proyecto representa una aplicacin de escritorio con soporte para WPF. Si tenemos en cuenta que WPF tambin se compone de cdigo XAML, es posible crear un entorno visual directamente desde Expression Blend 2. Librera de controles WPF: esta librera de controles est especializada en el encapsulamiento de elementos XAML y cdigo de programacin para su posterior reutilizacin en aplicaciones WPF. Debemos optar por esta opcin cuando queremos crear elementos reutilizables para ser incorporados en distintas aplicaciones. Sitio de Silverlight 1: este tipo de proyectos est orientado a crear sitios web con soporte para la versin 1 de Silverlight. Debemos tener en cuenta que este modelo no es tratado en este libro y adems representa una versin antigua del software. Aplicacin de Silverlight 2: una vez instalado el Service Pack 1 para Expression Blend 2, podremos ver esta clase de trabajos. ste es el tipo de proyectos sobre los cuales nos moveremos, tanto de manera visual como programtica.

Figura 5. Lista de proyectos incluidos en Expression Blend 2.

CONTROLES EN SILVERLIGHT

La mayora de los controles preestablecidos en Silverlight presentarn un comportamiento similar al de sus homnimos presentes en el desarrollo web y de escritorio. Al interactuar con ellos se deber, por consiguiente, imitar las mismas lneas de cdigo usadas en los dems ambientes de desarrollo con Microsoft .Net.

37

2. MICROSOFT EXPRESSION BLEND 2

Adems de poder indicar el nombre del proyecto que vamos a crear y la ubicacin fsica que tendr, es posible seleccionar el lenguaje de programacin con el cual preferimos trabajar. Vale aclarar que, para poder conseguir esta lista, es necesario haber instalado esos lenguajes en nuestra estacin de trabajo. El hecho de poder seleccionar un lenguaje de programacin se refiere a que cualquier cdigo que se realice desde Expression Blend 2 se har en ese lenguaje, por lo que es importante elegir aquel con el que estemos ms familiarizados.

Explorador de soluciones
Una vez que hemos creado el proyecto Silverlight 2, podremos navegar entre sus archivos desde el explorador de la solucin, que tpicamente puede ser encontrado a la derecha de la aplicacin, como podemos observar en la Figura 6. Este explorador nos mostrar, como elementos iniciales, una pgina del tipo XAML ms una clase creada en el lenguaje seleccionado, en este caso C#. Esta clase de C# es la que ser usada para generar el cdigo que maneje los elementos creados en la pgina XAML.

Figura 6. El explorador de soluciones (rea superior derecha) de Expression Blend 2 con los elementos iniciales de una aplicacin Silverlight 2.

RRR

INTEROPERABILIDAD

Para mejorar nuestro desarrollo en Expression Blend 2, es recomendable tener instalado, adems, alguna de las herramientas de desarrollo de software de Microsoft, como por ejemplo Visual Studio 2008. Esto har que, de tener que agregar cdigo de programacin a nuestro proyecto Silverlight, lo podamos hacer con mayor facilidad desde estas herramientas.

38

Un paseo por Expression Blend 2

Pgina inicial de Silverlight 2


El archivo Page.xaml es considerado la pgina o componente de inicio para nuestra aplicacin Silverlight 2, teniendo como contenido el siguiente cdigo:
<UserControl xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml x:Class=SilverlightApplication2.Page Width=640 Height=480> <Grid x:Name=LayoutRoot Background=White/> </UserControl>

En el caso de Silverlight 2, el elemento inicial es representado por un tag llamado <UserControl>. Lo que nos dice esto es que no ser considerado como una aplicacin en s misma, sino como un componente que puede ser incrustado o consumido por otras aplicaciones del tipo Silverlight, as como por aplicaciones web. En la misma declaracin de atributos de este control Silverlight, se incluye el nombre de la clase de C# encargada de manejar los componentes del control, as como el ancho y el alto, en pixeles, del control. Si exploramos el contenido de esa clase, podremos ver lo siguiente:
using using using using using using using using System; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Ink; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation;

RRR

DIMENSIONES DE SILVERLIGHT

Es posible hacer que nuestro control Silverlight se adapte a la superficie que lo contiene. Si colocamos el elemento Silverlight dentro de una tabla HTML y configuramos las propiedades del elemento para que sus atributos Width y Height sean igual a Auto, ste se adaptar de manera automtica a las dimensiones de su contenedor.

39

2. MICROSOFT EXPRESSION BLEND 2

using System.Windows.Shapes; namespace SilverlightApplication2 { public partial class Page : UserControl { public Page() { // Required to initialize variables InitializeComponent(); } } }

Esta clase, como ya comentamos, es la que ser usada como contenedor de la implementacin del cdigo que interactuar con los componentes colocados en la pgina XAML previamente vista. Esto quiere decir que, si queremos que nuestra aplicacin Silverlight consuma datos de una base de datos o reaccione apoyada en estmulos por parte del usuario, deberamos escribir esas lneas dentro de esta clase. Por supuesto, no estamos obligados a acumular todas las lneas de cdigo en este nico archivo ya que, como en todo lenguaje orientado a objetos, podremos crear tantas clases como necesitemos sin estar obligados a tener una pgina XAML por cada una. As, podramos encapsular la lgica de negocios o el acceso a datos en clases especializadas, y generar cdigo mantenible y fcilmente modificable.

La pgina App.xaml
La pgina App.xaml, junto con la clase de cdigo que la representa, es otro de los archivos creados inicialmente. Esta clase es usada en especial para almacenar cdigo XAML, que en el caso de App.xaml puede ser reusado dentro de todas las dems pginas de tipo XAML. Como podemos ver en el siguiente cdigo:

PATRONES DE DISEO DE SOFTWARE

Como una buena prctica en el desarrollo de software, encontramos los patrones de diseo de software. stos representan formas de crear cdigo para solucionar problemas especficos. Es importante tener presente estos patrones para mejorar la calidad del cdigo creado en Silverlight. Como resultado, obtendremos cdigo ms prolijo y ms fcil de modificar.

40

Un paseo por Expression Blend 2

<Application.Resources> <! Resources scoped at the Application level should be defined here. > <Style x:Key=TextBoxStyle1 TargetType=TextBox> <Setter Property=BorderThickness Value=1/> <Setter Property=Background> <Setter.Value> <LinearGradientBrush EndPoint=0.5,1 StartPoint=0.5,0> <GradientStop Color=#FFE8EFF1/> <GradientStop Color=#FF87DFF4 Offset=1/> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property=Foreground Value=#FFFF0000/> <Setter Property=Padding Value=2/> <Setter Property=BorderBrush> ... ...

En el cdigo anterior, el archivo App.xaml es usado para alojar la definicin de un nuevo elemento TextBox, que presenta ciertas particularidades de sus atributos de color y comportamiento, como podemos ver en la Figura 7. Este nuevo elemento, ahora, puede ser accedido y consumido por cualquier otro TextBox que se encuentre dentro de nuestra aplicacin. Por lo comn, cuando desarrollemos con Silverlight, tendremos la necesidad de crear nuestros propios esquemas visuales para que sean aplicados sobre controles especficos. Una forma de compartir estos esquemas es mediante su colocacin dentro de este archivo. De cualquier manera, hablaremos ms de estos esquemas y propiedades en los captulos 4 y 5.

RRR

TAMAO DE ARCHIVOS

Debemos tener cuidado en la cantidad de informacin que agregamos a nuestros archivos XAML, ya que stos deben ser descargados por el usuario. Un archivo de gran tamao tomar ms tiempo en ser descargado, en detrimento de la experiencia del usuario. Podemos usar carga por demanda para mejorar esta experiencia.

41

2. MICROSOFT EXPRESSION BLEND 2

Figura 7. El esquema generado puede ser aplicado a otros controles del mismo tipo en cualquier otra pgina de Silverlight.

Con respecto a la pgina de cdigo (App.xaml.cs), podemos decir que presenta un conjunto de eventos que se dispararn en determinados momentos de la vida de nuestra aplicacin. El cdigo genrico se muestra a continuacin, y luego lo analizaremos con ms detalle:
public App() { this.Startup += this.OnStartup; this.Exit += this.OnExit; this.UnhandledException += this.Application_UnhandledException; InitializeComponent(); } private void OnStartup(object sender, StartupEventArgs e) { // Load the main control here this.RootVisual = new Page(); } private void OnExit(object sender, EventArgs e) { }

42

Un paseo por Expression Blend 2

El primer mtodo, constructor de esta clase, se encarga de enlazar eventos inherentes al comportamiento de nuestra aplicacin. El mtodo OnStartup se ejecutar al inicio de la aplicacin, en este caso, podramos colocar cdigo en l para conseguir algn comportamiento necesario al momento de inicializarse nuestra aplicacin. Por ejemplo, podramos necesitar inicializar objetos o conectarnos a un servicio web, entre otras posibilidades. En el mismo caso, el evento OnExit ser disparado en el momento en el que la aplicacin sea cerrada o terminada, y de igual forma que en el caso anterior, podramos necesitar liberar ciertos recursos o realizar acciones especficas cuando la aplicacin concluya.

El entorno de Expression Blend 2


El entorno de Expression Blend 2 no se limita a los archivos previamente tratados. Si tenemos en cuenta que esta herramienta puede ser usada tanto por diseadores como por desarrolladores, podremos encontrar elementos tiles para los dos casos. Una de las secciones destacadas involucra el lienzo de dibujo central. En este lienzo, podremos arrojar y ordenar todos los controles incluidos en Silverlight, as como crear nuestros propios modelos y controles.

Figura 8. En este lienzo, podemos ver cmo son manipulados distintos controles de manera visual.

Desde esta rea central, tambin es posible interactuar en forma directa con el cdigo XAML. En nuestra interfaz podemos ver, en la parte superior derecha, las opciones para intercambiar entre los diferentes modos de visualizacin: Diseo, XAML o Dividir (mixto), y tenemos la posibilidad de modificar los componentes desde cualquiera de estas vistas. Si contamos con cierta experiencia en edicin de
43

2. MICROSOFT EXPRESSION BLEND 2

XAML, es probable que trabajemos en el modo mixto o de pantalla dividida, ya que esto puede acelerar nuestro trabajo de manera significativa. El prximo grupo de paneles que vamos a inspeccionar es el de las propiedades. ste se encuentra situado a la derecha de Expression Blend 2. Tpicamente, estas propiedades son el acceso rpido a las configuraciones de aspecto y comportamiento de los controles adicionados al lienzo de edicin. Para lograr la inspeccin de las propiedades de un control, primero ser necesario seleccionarlo. Segn el control seleccionado, las propiedades se vern afectadas en relacin a ste por lo que no contaremos con las mismas opciones en todos los casos.

Figura 9. Existen otras propiedades relacionadas con diferentes controles, slo debemos movernos usando la barra de desplazamiento ubicada a la derecha.

En esta rea tambin podemos encontrar, en la parte superior, opciones que tengan que ver con el proyecto. En especial, la pestaa relacionada con los recursos de la aplicacin, donde se listarn todos los atributos previamente configurados, como los alojados en el archivo App.xaml, que ya hemos tratado. La gran ventaja de esta lista de recursos radica en que podemos arrastrar cualquiera de estos

RRR

IMPLEMENTACIN DE CONTROLES

En Silverlight, no slo es posible modificar la apariencia visual de los controles nativos mediante la generacin de esquemas. Tambin podremos crear nuestros propios componentes y controles heredndolos en nuestro propio cdigo y creando nueva lgica funcional.

44

Un paseo por Expression Blend 2

elementos sobre alguno de los controles existentes para aplicar las configuraciones a ese control. El resultado de arrastrar el estilo configurado al inicio permite obtener lo que podemos ver en la siguiente figura.

Figura 10. El control de caja de texto posee, una vez aplicado, el estilo definido en el elemento TextBoxStyle1, que aparece debajo de la pestaa de recursos.

El ltimo panel que agrupa informacin sobre nuestra aplicacin Silverlight se encuentra a la izquierda del lienzo de dibujo. Sobre estos grupos, en la parte superior, se ubican las transformaciones y animaciones de los componentes de nuestra aplicacin. Aunque hablaremos de estas propiedades con mayor detalle en el captulo 5, vale recalcar que se pueden generar diferentes efectos de movimiento y transformaciones desde esta seccin. Debajo de este panel, se encuentra el rbol de controles de la pgina que estamos visualizando. Los controles se agruparn de manera jerrquica sobre la base del contenedor inmediato superior. Si tenemos en cuenta que los controles XAML pueden ser contenedores de otros controles XAML, esta estructura nos dar rpido acceso a cada uno de los elementos que componen un control de manera rpida. En la Figura 11, podemos ver un ejemplo de este rbol y del panel de animaciones.

_`

COMPRESIN DE ARCHIVOS

Todas las imgenes, videos y sonidos que agreguemos a nuestro proyecto, as como cualquier archivo externo, sern comprimidos en un nico archivo final con extensin XAP. Este archivo es, en realidad, un archivo zip que contiene todos los elementos creados por el proyecto Silverlight.

45

2. MICROSOFT EXPRESSION BLEND 2

Figura 11. En este rbol de controles se muestra la lista de elementos agregados antes a nuestro lienzo de dibujo, cmo stos son contenidos por una grilla y sta, a su vez, por el control Silverlight.

La barra de herramientas
Desde la barra de herramientas de Expression Blend 2, tendremos acceso a todos los controles y componentes preestablecidos de Silverlight y de Microsoft .Net Framework. Podemos separar la lista de controles en los siguientes grupos: Elementos de dibujo: son aquellos que nos dan acceso a herramientas de dibujo vectoriales. Con stos, podremos dibujar lneas, curvas, crculos y rectngulos.

Figura 12. Listas de controles para dibujo vectorial.

Contenedores y agrupadores: la tarea de estos elementos consiste, principalmente, en agrupar otros controles Silverlight, aunque tambin se encargan de ordenar, dentro de la superficie de dibujo, la disposicin de esos elementos. As,
46

Un paseo por Expression Blend 2

podemos encontrar grillas, donde se definirn filas y columnas (agregando dentro de cada celda distintos controles y componentes) o elementos de barras de desplazamiento para colocar contenido que exceda los lmites de ancho o alto definidos para una zona de nuestra aplicacin.

Figura 13. Controles para la agrupacin y contencin de otros elementos y controles.

Interaccin con el usuario: este ltimo grupo representa aquellos controles y componentes que sirven para capturar comportamiento por parte del usuario. Dentro de los ms conocidos, podemos encontrar los botones, cajas de texto, listas desplegables y botones de seleccin mltiple, entre otros.

Figura 14. Controles ms comunes para capturar informacin por parte del usuario.

Los controles antes nombrados suelen ser los que se usan con mayor frecuencia para el desarrollo de aplicaciones con Silverlight, pero existen otros que no se ven de forma directa. Para poder acceder a ellos, es necesario seleccionar el ltimo elemento de la lista en la barra de herramientas. Al hacerlo, podremos ver la lista completa de controles disponibles y agregarlos a nuestra coleccin de controles, como se muestra a continuacin.
47

2. MICROSOFT EXPRESSION BLEND 2

Figura 15. Todos los controles disponibles desde Expression Blend 2.

Crear nuestra primera aplicacin con Expression Blend 2


Ya estamos en condiciones de comenzar a trabajar con Expression Blend 2 para crear nuestra primera aplicacin Silverlight. En este caso, crearemos un visor simple de videos. Este visor deber contemplar las posibilidades de iniciar, pausar y detener, en forma completa, una pelcula designada por nosotros. El primer paso es crear una nueva aplicacin Silverlight 2. Una vez hecho esto, necesitaremos agregar a nuestro lienzo de dibujo un control del tipo MediaElement, que sirve para representar videos, imgenes y sonidos en Silverlight. Para poder agregar este control, es necesario que lo busquemos en la lista completa de controles Silverlight, como vimos en la Figura 15, ya que no se encuentra disponible en la barra de herramientas. Junto con este control, agregaremos alguno del tipo Border. Este control es necesario para darle una apariencia de caja a nuestra pelcula, debido aque el control MediaElement no posee caractersticas. Podemos obtener un cambio en la configuracin visual del control Border si modificamos sus caractersticas en la pestaa Propiedades. Para este caso,

_`

CADA VEZ MS SE INCLINAN POR SILVERLIGHT

A medida que Silverlight va madurando, ms empresas y portales en la Web se inclinan por la utilizacin de esta tecnologa sobre otras. Uno de los ltimos portales que opt por modificar toda su implementacin de servicios para los usuarios fue Terra, al cambiar su utilizacin de Adobe Flash por Silverlight.

48

Un paseo por Expression Blend 2

debemos modificar las propiedades del fondo (Background), para que se aplique el color degradado, y las de apariencia, colocando el grosor del borde del control (BorderThikness) en 1 y el radio de curvatura de las esquinas (CornerRadius) en 10.

Figura 16. Propiedades aplicadas al control Border.

Por ltimo, el control MediaElement debe ser contenido por el control que representa el borde configurado previamente. Para esto, arrastramos el control MediaElement dentro del control Border para lograr el efecto deseado. Como podemos editar directamente XAML, es posible lograr el mismo fin con las siguientes lneas de cdigo:
<Border Margin=95.5,57,91.5,217 BorderBrush=#FF000000 BorderThickness=1,1,1,1 CornerRadius=10,10,10,10> <Border.Background> <LinearGradientBrush EndPoint=0.5,1 StartPoint=0.5,0> <GradientStop Color=#FF6985B5/> <GradientStop Color=#FFFFFFFF Offset=1/> </LinearGradientBrush> </Border.Background> <MediaElement Height=Auto Width=Auto OpacityMask={x:Null}/> </Border>

Por ltimo, es necesario que agreguemos tres botones para las tres acciones antes definidas. Podremos cambiarle el texto que se va a mostrar en cada botn, presionando dos veces con el puntero del ratn sobre el control, o mediante sus propiedades. El resultado debera ser similar al mostrado en la siguiente figura.
49

2. MICROSOFT EXPRESSION BLEND 2

Figura 17. Nuestro visor de videos con los botones que controlarn la reproduccin.

Una vez conseguido el visor de videos, es necesario configurar el control MediaElement para especificarle cul ser el video que se va a reproducir. Seleccionamos el control MediaElement en la lista de propiedades y buscamos la fuente de contenido (Source). Por lo general, podremos seleccionar formatos soportados por Silverlight de los que hablaremos con ms detalles en el captulo 6 cuando veamos el componente MediaElement de manera especial. Una vez que hemos seleccionado el video en cuestin, presionamos la tecla F5 para inicializar la aplicacin. Esta accin deber iniciar un explorador de Internet y desplegar la aplicacin creada. Podremos notar que el video se reproduce con normalidad, pero los botones creados para cada una de las acciones no funcionan como esperbamos, debido a que no hemos generado ningn cdigo que las realice (Figura 18). Para conseguirlo, el primer paso es asignarle un nombre a nuestro MediaElement, ya que sin l no podremos acceder a las propiedades del control, por lo que no ser posible iniciarlo, pausarlo o detenerlo. Podemos asignarle el nombre al control seleccionndolo y agregndole el mismo que tiene en la lista de propiedades o mediante XAML por medio del atributo x:Name=Nombre del Control. El elemento MediaElement quedar como se ve en el siguiente cdigo:

RRR

INTERFACES DE USUARIO

Si necesitamos buscar material sobre desarrollo de interfaces visuales, es posible que tambin las encontremos mediante la sigla UX (User eXperience o experiencia de usuario, por su significado en ingls). Debido a que el trmino, con el tiempo, mut, tendremos ms chances de hallar informacin mediante este ltimo nombre.

50

Un paseo por Expression Blend 2

<MediaElement Height=Auto Width=Auto Source=silverlight.wmv AutoPlay=False x:Name=visorVideo/>

Figura 18. El visor de videos trabajando de manera correcta en nuestro navegador.

Si tenemos en cuenta que la lgica debe ser creada en la clase de cdigo C#, necesitaremos escribir algunas lneas en ella para realizar las acciones propuestas por los tres botones. Tenemos varios caminos para lograrlo: podramos usar Visual Studio 2008 para generar el cdigo. Visual Studio 2008 es una herramienta de alto nivel para la creacin de cdigo para aplicaciones, as como para realizar pruebas sobre l. Por otro lado, sera posible modificar el archivo de clase y el cdigo XAML por nuestra cuenta. Sin embargo, esto puede redundar en un aumento de trabajo y del tiempo de desarrollo y crear posibles problemas en la confeccin del cdigo, si no somos experimentados conocedores del lenguaje de programacin utilizado. De cualquier manera, para este ejemplo, si optamos por la segunda opcin, slo deberemos seguir unos cuantos pasos. Primero, en el cdigo XAML, tendremos que agregar el atributo Click=Nombre del Mtodo por cada botn creado. Click representa el evento por el

RRR

SERVIDOR WEB

Expression Blend 2 trae consigo un pequeo servidor de pginas web. Este servidor es activado en el momento en que queremos depurar nuestro trabajo y ver los resultados obtenidos. Gracias a este servidor, no dependeremos de grandes infraestructuras para desplegar y ejecutar nuestros proyectos cada vez que necesitemos validar lo que estemos desarrollando.

51

2. MICROSOFT EXPRESSION BLEND 2

cual se disparar la accin o la lgica contenida en el mtodo o funcin creada en el cdigo C#. As, cuando el usuario presione el botn en cuestin, el evento Click ser disparado y se desencadenar toda la lgica que hayamos programado. Es necesario, entonces, que modifiquemos nuestro XAML para agregar los tres eventos:
<Button Height=33 HorizontalAlignment=Left Margin=95.5,0,0,162 VerticalAlignment=Bottom Width=76.5 Content=Iniciar RenderTransformOrigin=0.481,0.515 Click=Iniciar/> <Button Height=33 HorizontalAlignment=Left Margin=193,0,0,162 VerticalAlignment=Bottom Width=76.5 RenderTransformOrigin=0.481,0.515 Content=Pausar Click=Pausar/> <Button Height=33 Margin=287,0,276,162 VerticalAlignment=Bottom Width=76.5 RenderTransformOrigin=0.5,0.5 Content=Detener Click=Detener/>

Estos tres eventos ahora hacen referencia a tres funciones: Iniciar, Pausar y Detener. Para agregar la lgica que maneje estas acciones, necesitamos modificar nuestra clase C#. Si no contamos con Visual Studio 2008, podremos abrirla con el bloc de notas o cualquier editor de texto. El resultado final debera ser como el que sigue:
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using using using using System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes;

namespace SilverlightApplication2 { public partial class Page : UserControl { public Page() {

52

Un paseo por Expression Blend 2

// Required to initialize variables InitializeComponent(); } private void Iniciar(object sender, RoutedEventArgs e) { visorVideo.Play(); } private void Pausar(object sender, RoutedEventArgs e) { visorVideo.Pause(); } private void Detener(object sender, RoutedEventArgs e) { visorVideo.Stop(); } } }

En el cdigo anterior, vemos cmo una simple lnea de cdigo por accin puede ejecutar, pausar o detener el video. Si volvemos a ejecutar nuestra aplicacin Silverlight, deberemos poder interactuar con el video seleccionado mediante los botones, inicindolo, detenindolo y pausndolo.

RESUMEN
Expression Blend 2 es una herramienta altamente flexible que une dos reas del desarrollo de software que haban estado separadas y con falta de comunicacin. De esta forma les da tanto a los diseadores como a los desarrolladores una forma de comunicarse para que los primeros puedan ver plasmadas sus ideas en las aplicaciones tal cual las han concebido, y los desarrolladores implementen estas ideas sin la necesidad de reescribir cdigo, para no invertir tiempo y esfuerzo de manera innecesaria.

53

 ACTIVIDADES
PREGUNTAS TERICAS
1 Cul es, en el desarrollo web, el principal problema con el que se encuentra un desarrollador al recibir el trabajo del diseador para ser implementado? 2 Por qu es importante poner esfuerzo en el rea de experiencia visual del usuario? 3 Qu herramientas intentan unir el diseo y el desarrollo de software? 4 Por qu es importante la creacin de prototipos visuales en el desarrollo de software? 5 Podemos encontrar todos los controles y componentes HTML representados en Silverlight con XAML? 6 Qu tipos de proyectos es posible crear con Expression Blend 2? 7 Es necesario instalar algn programa adicional para poder desarrollar aplicaciones Silverlight 2 con Expression Blend 2? 8 Si queremos ver todos los controles de Expression Blend 2, cmo accedemos a ellos? 9 Es necesario contar con un servidor web para depurar las aplicaciones Silverlight desde Expression Blend 2? 10 Cuntos tipos de controles encontramos en Silverlight? Cmo los categorizamos? 5 Visite el sitio de experiencia para el usuario de Microsoft (www.microsoft.com/ design) para maximizar el conocimiento sobre posibilidades involucradas en esta rea de la ingeniera de software. 3 Intente crear un visor de videos por Internet, ejecutando la aplicacin creada mediante el uso de IIS (Internet Information Services). 4 Ingrese en www.microsoft.com/surface, el sitio web de Microsoft Surface, para ver buenos ejemplos de interfaces visuales y su aplicacin en soluciones de software.

EJERCICIOS PRCTICOS
1 Ingrese y navegue por Quince (http:// quince.infragistics.com), el sitio web de Infragistics dedicado a la mejora de las interfaces visuales. 2 Dirjase al sitio web oficial de Silverlight (http://silverlight.net) para ver ms ejemplos sobre esta plataforma.

54

Silverlight

Captulo

El mejor trabajo, con la mejor herramienta


Ms all de nuestro conocimiento, la forma ms eficiente de crear viene de la mano de la mejor herramienta disponible. As como los diseadores visuales tienen una herramienta creada para ellos, los desarrolladores no se pueden quedar atrs. Visual Studio 2008 y Silverlight son una mezcla con la que podremos obtener cdigo de extrema calidad.
Silverlight para desarrolladores Puesta a punto de Visual Studio 2008 Silverlight 2 con Visual Studio Crear la primera aplicacin con Visual Studio 2008 Interoperabilidad con Expression Blend 2 Resumen Actividades 56 56 59 63 76 79 80

SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com

3. EL MEJOR TRABAJO, CON LA MEJOR HERRAMIENTA

SILVERLIGHT PARA DESARROLLADORES


En este punto, ya hemos pasado por los conceptos iniciales de Silverlight y recorrimos un poco una de las herramientas provistas por Microsoft, Expression Blend 2, para desarrollar aplicaciones para esta plataforma. En este captulo, hablaremos de Visual Studio 2008 como la herramienta ideal para los desarrolladores de software y tambin para desarrollar aplicaciones Silverlight. Adems, crearemos una nueva aplicacin que consuma datos y se los mostraremos al usuario.

Puesta a punto de Visual Studio 2008


En el primer captulo, comentamos que la versin 2 de Silverlight no viene incluida en Visual Studio 2008 y, por consiguiente, es necesario que hagamos esta instalacin descargando los componentes desde la pgina de Microsoft. El motivo de esta seccin en este captulo se debe a que, en muchas ocasiones, nos encontramos con el dilema de no saber qu versin, componente u herramienta descargar. En general, los sitios de los proveedores suelen presentarnos ms de una versin disponible para su descarga, pero si elegimos una incorrecta nos retrasar en nuestro trabajo, as como tambin podemos encontrarnos con algn funcionamiento inesperado mientras realizamos nuestro trabajo. En la Figura 1, se ilustra el sitio web de Microsoft que representa el portal de entrada para Silverlight.

Figura 1. Portal de Silverlight en Microsoft.com.

En esta figura, se muestra una lista de componentes que pueden ser descargados. El primero hace referencia al motor o plugin de Silverlight. Este motor es el que
56

Silverlight para desarrolladores

debe instalar todo usuario que quiera ver las aplicaciones Silverlight desde el navegador. Por supuesto, no es necesario que proveamos por nuestra cuenta este plugin ni que tengamos que instalarlo de forma manual en cada uno de los equipos y de los navegadores que quieran nuestro producto ya que, en la declaracin del objeto Silverlight en el cdigo HTML, se incluye una comprobacin de versiones, adems de indicarle al navegador de dnde obtener esta versin:
<object data=data:application/x-silverlight, type=application/xsilverlight-2 width=100% height=100%> <param name=source value=SilverlightApplication1.xap/> <param name=onerror value=onSilverlightError /> <param name=background value=white /> <param name=minRuntimeVersion value=2.0.31005.0 /> <param name=autoUpgrade value=true /> <a href=http://go.microsoft.com/fwlink/?LinkID=124807 style=textdecoration: none;> <img src=http://go.microsoft.com/fwlink/?LinkId=108181 alt=Get Microsoft Silverlight style=border-style: none/> </a> </object>

Este cdigo es el que deberemos usar de manera habitual para la incrustacin de aplicaciones Silverlight en pginas webs. Si analizamos las partes del cdigo, vemos que, dentro del atributo data, se detalla el tipo de componente por ejecutar. De esta forma, el navegador sabr que el objeto requerido es del tipo Silverlight. El atributo type especfica la versin de aplicacin que se usar, en nuestro caso, Silverlight 2. Los elementos param, con sus atributos name, preconfiguran la aplicacin Silverlight. La propiedad onerror especifica el nombre de la funcin JavaScript que se ejecutar si ocurriera un error en el transcurso del implemento de la aplicacin. Por su parte, minRuntimeVersion detalla la versin exacta de la aplicacin, por lo que deberemos tener el plugin compatible para poder ejecutarla.

QU ES SILVERLIGHT EN REALIDAD?

Este software no es un componente para realizar presentaciones vistosas en Internet. Por el contrario, Silverlight no slo cumple con esta caracterstica, sino que extiende el desarrollo de aplicaciones profesionales al ambiente web con contenido dinmico. Podemos usar Silverlight, en especial, cuando tengamos que resolver problemas complejos desde la Web.

57

3. EL MEJOR TRABAJO, CON LA MEJOR HERRAMIENTA

El parmetro autoUpgrade representa la capacidad del navegador para descargar en forma automtica alguna nueva versin detectada, previa autorizacin del usuario. Por ltimo, si el navegador no cuenta con la versin indicada o simplemente no tiene el plugin instalado, la pgina mostrar la imagen de la figura siguiente, con un vnculo a la versin descargable del plugin.

Figura 2. Al no tener el plugin instalado, el usuario ver la imagen que le sugiere descargar el complemento.

El segundo elemento de la lista de la Figura 1 representa todas las herramientas y SDKs (Software Development Kits o, en castellano, Grupo de herramientas para desarrollo). Necesitaremos descargar e instalar este conjunto de herramientas slo si ya contamos con las plantillas y actualizaciones de Visual Studio 2008. El tercer elemento es el ms completo, ya que involucra el SDK y, adems, incluye las actualizaciones para Visual Studio 2008, as como las plantillas necesarias para el desarrollo de aplicaciones Silverlight. En forma independiente del elemento elegido, la descarga y su posterior instalacin siguen el patrn de cualquier aplicacin bajo Windows. Basta con seguir los pasos provistos por el asistente para lograr una correcta instalacin. Podremos comprobar que las herramientas se han instalado de manera correcta creando un nuevo proyecto desde Visual Studio

NUEVAS VERSIONES DE SILVERLIGHT

Al momento de escribir este libro, se realiz el anuncio por parte de Microsoft de la nueva versin de Silverlight: Silverlight 3, versin que se encuentra en etapa beta. Si instalamos esta versin, no podremos seguir trabajando con la 2, que es la utilizada en este libro. Es recomendable usar mquinas virtuales para instalar versiones beta.

58

Silverlight para desarrolladores

2008. Al crear el nuevo proyecto (men Archivo/Nuevo/Proyecto), deberemos tener la capacidad de ver el submen relacionado con Silverlight en el rbol de tipos de proyectos, dentro del lenguaje de programacin elegido. Al seleccionarlo, se vern las plantillas como se muestran en la siguiente figura.

Figura 3. Silverlight con C#. Al crear un proyecto, vemos plantillas de Silverlight.

Silverlight 2 con Visual Studio


Si en el captulo anterior identificamos a Expression Blend 2 como la herramienta ideal para el diseador grfico y para crear interfaces visuales en aplicaciones de software, podemos decir que Visual Studio 2008 es la ideal para los desarrolladores de software. En este grupo se incluyen tanto los programadores o codificadores, como los arquitectos de software, aseguradores de la calidad del producto y otros relacionados con la generacin de la pieza de software. Esto quiere decir que, con Visual Studio 2008, nos focalizaremos en las lneas de cdigo, por lo que el trabajo realizado sobre las aplicaciones estar planteado desde esta ptica y no relacionado en forma directa con la interfaz propiamente dicha.

RRR

EL NOMBRE DE LA INTERFAZ DE USUARIO

Es posible traducir a Interfaz de usuario el nombre que comnmente podremos encontrar en ingeniera informtica y que hace referencia a UI (User Interface en ingls). Este trmino se refiere a los componentes visuales involucrados en el software y que se relacionarn con el usuario que lo utilice.

59

3. EL MEJOR TRABAJO, CON LA MEJOR HERRAMIENTA

Figura 4. La caja de herramientas de Visual Studio 2008.

De todas maneras, si bien es posible utilizar esta herramienta para realizar todo el proceso, al mismo tiempo el desarrollador no debe olvidar la interfaz visual, ya que su cdigo tendr que adaptarse a las necesidades que se pudieran plantear tanto por el usuario como por el diseador. Como dijimos en captulos anteriores, siempre ser preferible, dentro del grupo de desarrollo o produccin de software, contar con las habilidades y roles necesarios para generar el producto, dejando que cada uno, desde su rol y experiencia, realice el trabajo designado. Entonces, hacer uso de las dos herramientas, Visual Studio 2008 y Expression Blend 2, crear un ambiente de desarrollo ideal, porque tiene en cuenta los roles involucrados y preocupados por satisfacer las necesidades de sus reas de inters, las cuales representan, en cierta medida, las necesidades del cliente. Como resultado, se obtendr una mejor experiencia por cada una de las partes involucradas, ya que cada una estar enfocada en resolver el dominio de su problema y no, el de otros. Con esto queremos destacar que, si bien el desarrollador se encarga de la lgica y del cdigo, no debera olvidar lo relacionado con interfaces grficas, por lo que tener conocimientos de Expression Blend 2, aunque sea en menor medida que de Visual Studio 2008, le otorgar mayor criterio a la hora de entender e implementar lo que el diseador grfico le proporcione. Con Visual Studio 2008, no slo podremos crear aplicaciones Silverlight, sino que adems nos es posible enriquecerlas desde el punto de vista del cdigo. En la barra de herramientas, notaremos que existen controles y componentes que no son mostrados en Expression Blend 2. Esto se debe a que los componentes, como Calendar, DataGrid o DatePicker, son ideales para la interaccin con datos y slo se muestran desde el inicio para los desarrolladores, aunque no para los diseadores, lo que no significa que no podamos utilizarlos desde Expression Blend 2. Si exploramos con mayor profundidad dentro de las aplicaciones Silverlight creadas desde Visual
60

Silverlight para desarrolladores

Studio 2008, notaremos que, como todo desarrollo profesional de software, es posible agregar diferentes capas o niveles de cdigo a esta aplicacin. Se podr, por ejemplo, consumir informacin desde un servicio web remoto y desplegar estos datos a los usuarios. Hablaremos ms de este tema en el captulo 7.

Figura 5. Agregado de una referencia web a nuestra aplicacin Silverlight.

Otra de las cualidades ms interesantes las presenta el asistente de escritura de cdigo IntelliSense, que se usa, en especial, para la escritura de cdigo manejado (C#, Visual Basic.Net, etctera), pero en este caso con soporte total para XAML, para acelerar la produccin de estas lneas de cdigo.

Figura 6. IntelliSense para XAML, mostrando las propiedades disponibles de un componente TextBlock.
61

3. EL MEJOR TRABAJO, CON LA MEJOR HERRAMIENTA

Por ltimo, una de las capacidades ms importantes que tiene Visual Studio 2008 cuando trabajamos con aplicaciones Silverlight es la depuracin de cdigo en tiempo de ejecucin. Con esta caracterstica, heredada del desarrollo tradicional de aplicaciones, podremos colocar puntos de interrupcin en nuestro cdigo y movernos lnea a lnea una vez que la aplicacin est trabajando. La ventaja de esta posibilidad radica en que, si encontramos un error en tiempo de ejecucin de nuestra aplicacin, podremos depurarla paso a paso para hallar el problema. Esto resultara en extremo complicado si tuviramos que hacer el trabajo mediante la inspeccin de las lneas y el clculo de los estados de las variables y objetos en cada paso. Para lograrlo, podremos agregar un punto de interrupcin con un clic del mouse en la parte extrema izquierda de nuestro cdigo por cada lnea en la que queramos que la ejecucin se detenga.

Figura 7. Algunos puntos de interrupcin en nuestro cdigo.

Cuando ejecutamos nuestra aplicacin Silverlight, notaremos que la ejecucin del cdigo se detiene en cada uno de los puntos de interrupcin declarados, donde podemos inspeccionar las variables y objetos en el estado que se encuentren

RRR

BARRA DE HERRAMIENTAS EN VISUAL STUDIO 2008

Si no se encuentra visible la barra de herramientas de Visual Studio 2008, podemos hacerla aparecer con la combinacin de teclas CTRL+ALT+X, dependiendo del tipo de configuracin que hayamos elegido inicialmente, o si no, desde el men Ver/Caja de Herramientas.

62

Silverlight para desarrolladores

en ese momento. En la figura que aparece a continuacin, se muestra cmo el cdigo se detiene, y uno de los objetos es inspeccionado.

Figura 8. El cdigo es detenido para evaluar el estado de los objetos.

Microsoft Visual Studio 2008 no es slo una potente herramienta para el desarrollo de software convencional, sino que, adems, todas sus prestaciones pueden ser usadas para el desarrollo de aplicaciones Silverlight. Por esto, as como el diseador visual encuentra su lugar en Expression Blend 2, los desarrolladores de cdigo lo harn en Visual Studio 2008.

Crear la primera aplicacin con Visual Studio 2008


En el captulo anterior, pudimos crear un reproductor de videos con Expression Blend 2 y Silverlight. En este caso, y conociendo ms a fondo las prestaciones de Visual Studio 2008, crearemos otra aplicacin Silverlight, pero con el enfoque en la manipulacin de datos. Para este caso, haremos un buscador de productos, con controles que actuarn de filtro de bsqueda y una lista de registros o grilla que muestre los resultados encontrados. En este ejemplo, tambin usaremos LinQ para realizar consultas sobre objetos, caractersticas que trataremos con mayor profundidad en el captulo 7. Como primer paso, es necesario crear una nueva aplicacin Silverlight 2 desde Visual Studio 2008. Esto lo logramos desde al men Archivo y, luego, Nuevo proyecto. En el rbol de soluciones, debemos buscar la opcin de proyectos Silverlight para ver las plantillas de este tipo de proyectos. Una vez seleccionado el lenguaje de programacin que usaremos, nos posicionamos sobre el tipo de proyecto Silverlight donde podremos ver las plantillas disponibles. En este caso, seleccionaremos la plantilla Aplicacin de Silverlight para poder probar directamente nuestro proyecto; para ello, utilizaremos
63

3. EL MEJOR TRABAJO, CON LA MEJOR HERRAMIENTA

alguna aplicacin ASP.net existente o crearemos una pgina de prueba para nuestra aplicacin. Si no vemos las plantillas Silverlight disponibles, usamos Visual Studio 2008 o superior y ya hemos instalado los aditamentos mencionados en el captulo 1, es necesario asegurarnos de haber seleccionado la versin correcta de Microsoft .Net Framework desde la lista desplegable en la parte superior derecha del asistente para creacin de proyectos, como podemos ver a continuacin.

Figura 9. Es importante seleccionar la versin 3.5 de Microsoft .Net Framework para poder ver las plantillas de Silverlight.

Una vez cumplidos los pasos anteriores, Visual Studio nos preguntar sobre la modalidad que utilizaremos para depurar la aplicacin Silverlight, y nos permitir elegir entre las siguientes opciones: Crear un nuevo proyecto ASP.net: esta opcin agregar un proyecto adicional del tipo ASP.net a la solucin e incrustar, de manera automtica, nuestro proyecto Silverlight a la pgina por defecto. Cuando depuremos la solucin, Visual Studio abrir la pgina ASP.net para mostrar el componente Silverlight creado por nosotros.

RRR

TIEMPO DE EJECUCIN

En varias ocasiones, hablaremos de tiempos de ejecucin y tiempo de compilacin. Tiempo de compilacin hace referencia al momento en el que nuestro cdigo es transformado en un ejecutable. Tiempo de ejecucin alude, en cambio, al momento en que nuestro cdigo se ejecuta.

64

Silverlight para desarrolladores

Generacin automtica de una pgina: en este caso, Visual Studio no crear ninguna pgina ni proyecto adicional a la solucin y slo veremos el proyecto Silverlight en el cual trabajaremos. Cuando intentemos depurar la aplicacin Silverlight, Visual Studio crear una pgina de manera dinmica en la que podremos ver y probar el funcionamiento de nuestro componente Silverlight. Vincular el control Silverlight: si ya contamos con un sitio web previamente creado, podremos usar esta opcin para vincular el proyecto Silverlight con aqul y depurarlo basado en esta implementacin existente. Deberemos seleccionar esta opcin cuando queramos trabajar en forma directa sobre nuestras implementaciones web y hacer interactuar nuestro proyecto Silverlight con el ambiente real donde ser desplegado.

Figura 10. En la imagen, vemos las tres opciones disponibles para crear nuestra aplicacin Silverlight.

Para este ejemplo, seleccionaremos la segunda opcin, ya que no necesitaremos interactuar con nuestra aplicacin Silverlight de manera externa o desde el navegador del cliente. Una vez creado el proyecto, Visual Studio 2008 nos presentar el lienzo

RRR

LENGUAJES DISPONIBLES

La lista de lenguajes disponibles en Visual Studio vara sobre la base de los que hayamos instalado junto con la herramienta. En una instalacin tpica, podremos elegir entre Visual C++, C#, Visual Basic.net y J#. Para poder usar lenguajes de otros fabricantes, deberemos adquirirlos desde sus respectivas pginas webs.

65

3. EL MEJOR TRABAJO, CON LA MEJOR HERRAMIENTA

de dibujo de Silverlight y, en la misma pantalla, el cdigo XAML que representa este lienzo. Al igual que Expression Blend 2, el cdigo inicial se ve como sigue:
<UserControl x:Class=SilverlightApplication1.Page xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml Width=400 Height=300> <Grid x:Name=Layout Background=White> </Grid> </UserControl>

La principal desventaja que presenta trabajar con Visual Studio 2008 es que no podremos modificar el lienzo directamente, como en el caso de Expression Blend 2, sino que deberemos trabajar todo desde el cdigo XAML, lo que requerir de nosotros mayor dominio de ste para conseguir el resultado final.

Figura 11. Vista inicial de una aplicacin Silverlight creada con Visual Studio 2008.

_`

VISUAL STUDIO Y LAS VERSIONES DE .NET FRAMEWORK

Visual Studio 2008 tiene la particularidad de soportar el desarrollo para diferentes versiones de .Net Framework. Gracias a ello, se convierte en una herramienta verstil, que permite editar proyectos creados en versiones anteriores de Visual Studio as como crear proyectos para versiones previas a la ltima versin del Framework.

66

Silverlight para desarrolladores

En este ejemplo, haremos uso del contenedor Grid para agrupar y ordenar nuestros elementos. Por un lado, necesitaremos alguna forma de permitir que el usuario escriba lo que quiere buscar, capturando dicha entrada y proporcionando la posibilidad de activar la bsqueda. Esto podemos conseguirlo mediante un componente TextBox y un componente Button. Estos controles deberemos alinearlos de tal manera que se vean uno al lado del otro. Para conseguir este efecto, agregaremos un par de filas y de columnas al contenedor Grid inicial de la siguiente manera:
<Grid x:Name=Layout Background=White> <Grid.RowDefinitions> <RowDefinition Height=40/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> </Grid>

El tag <Grid.RowDefinitions> deberemos utilizarlo para agrupar la cantidad de filas que contendr esta grilla; cada elemento <RowDefinition> representar especficamente una fila de la grilla, pudiendo definir por cada una sus dimensiones. Por otro lado, el tag <Grid.ColumnDefinitions> representa la coleccin de columnas que contendr la grilla, pudiendo definir elementos <ColumnDefinition> dentro de sta, los que especificarn cada una de las columnas por visualizar. La grilla definida slo servir como organizador de los dems controles y componentes y no para mostrar los datos propiamente dichos. El siguiente paso consiste en agregar un TextBox y un botn, los que ubicaremos en la primera fila, y primera y segunda columna de nuestra grilla. Podemos ver el resultado en el siguiente cdigo:

RRR

CONTROLES Y COMPONENTES

En los captulos se hace referencia a controles y componentes. stos deben ser entendidos como piezas de software, cdigo funcional encapsulado para su posterior reutilizacin. Los controles suelen tener comportamiento visual mientras que los componentes, no.

67

3. EL MEJOR TRABAJO, CON LA MEJOR HERRAMIENTA

<TextBox Grid.Row=0 Grid.Column=0 x:Name=txtBusqueda Margin=5,5,5,5></TextBox> <Button Grid.Row=0 Grid.Column=1 Width=100 HorizontalAlignment=Right Margin=0,5,5,5 Content=Buscar></Button>

Para ubicar los componentes en el rea de la grilla, es necesario determinarlo en el mismo control y no, como podramos estar acostumbrados en HTML o lenguajes similares, dentro de la definicin de la fila y la columna. Por este motivo, haremos uso del atributo Grid.Row y Grid.Column para determinar la celda en la cual se visualizar el control. La coleccin de filas y de columnas se representa mediante un ndice con base 0 por lo que, si hacemos referencia a la primera fila y a la primera columna, tendremos que usar el 0 (cero) en ambos casos. Otros de los atributos que podemos observar es el de x:Name para el componente TextBox. Con l, accederemos a la informacin escrita por el usuario para hacer la bsqueda respectiva; el atributo Margin nos permite agregar al control mrgenes en pixeles para que no cubra la totalidad de la celda (es posible asignarles mrgenes izquierdos, superiores, derechos e inferiores, en ese orden, separados por comas). En el caso del botn, el atributo Content representa el texto por mostrar dentro del componente. En el siguiente paso agregaremos una grilla con capacidades de manipulacin de datos. Para esto, deberemos seleccionarla y arrastrarla desde la barra de herramientas de Visual Studio. Al hacerlo, veremos que, adems del cdigo XAML, tambin se adicionar una nueva referencia a nuestro proyecto. Esta referencia es System.Windows.Controls.Data y es necesaria para utilizar aquellos componentes con soporte de enlazado de datos, en este caso el control DataGrid.

Figura 12. Si arrastramos y soltamos un DataGrid a nuestro proyecto, accederemos a un control listo para usar con la capacidad de desplegar registros.
68

Silverlight para desarrolladores

Este DataGrid tambin necesitar ser asignado a una fila y a una columna dentro de la grilla general, de la siguiente manera:
<data:DataGrid Grid.Row=1 Grid.Column=0 x:Name=GrillaDeProductos Grid.ColumnSpan=2 AutoGenerateColumns=True> </data:DataGrid>

Figura 13. Lista de referencias en nuestro proyecto, incluyendo System.Windows.Controls.Data para el manejo del DataGrid.

Una vez ms, los atributos Grid.Row y Grid.Column son utilizados para posicionar este componente en una de las celdas de la grilla, aunque en este caso aparece un nuevo atributo llamado Grid.ColumnSpan. Este atributo es necesario para decirle al DataGrid que debe emplear u ocupar las dos columnas de la fila en la cual se encuentra. Si obviramos este parmetro, obtendramos un resultado no deseado, como podemos ver en la figura de la siguiente pgina.

RRR

NUEVO C#

Como estamos trabajando con la ltima versin del lenguaje C#, encontraremos mejoras que facilitarn la rpida escritura del cdigo. En la versin 2008 del lenguaje, no se requiere que escribamos el contenido de los get y set en las propiedades y sus respectivas variables privadas, ya que lo har por nosotros cuando se genere el programa.

69

3. EL MEJOR TRABAJO, CON LA MEJOR HERRAMIENTA

Figura 14. Al no especificar cuntas columnas ocupar el DataGrid, ste slo se enfoca en la primera, dando un aspecto no deseado para este caso.

Otro atributo nuevo que aparece es el AutoGenerateColumns, que especifica que las columnas del DataGrid se crearn por cuenta propia sobre la base de la informacin enviada, por lo que, si nuestra coleccin de datos posee N columnas, stas sern representadas por el componente. En este punto, ya tenemos toda la interfaz visual creada, por lo tanto, pasaremos a crear el cdigo C# que realice las bsquedas basadas en la entrada del usuario. Sobre el proyecto, agregaremos una nueva clase C# (productos.cs) que usaremos como entidad contenedora de datos. Esto podemos lograrlo por medio de un clic con el botn secundario del mouse sobre el proyecto Silverlight y con la adicin de un nuevo tem. En el asistente, seleccionaremos la opcin de cdigo y, a continuacin, la plantilla para nuevas clases. Esta clase debe contener la descripcin de todos los campos que necesitaremos desplegar o por los que realizaremos bsquedas en nuestro cdigo. Al tratarse de la representacin de productos, sta podra contener algunas propiedades como identificador del producto, nombre del producto, descripcin, precio, cantidad en stock y otras que se adecuen al negocio. La clase producto debera quedar como sigue:

RRR

MICROSOFT INTELLISENSE

Intellisense resulta extremadamente til para completar cdigo. Desde Visual Studio podemos activarlo con la combinacin CTRL+J. En el desarrollo de aplicaciones Silverlight no slo es posible usar Intellisense en cdigo C#, tambin est disponible para cdigo XAML.

70

Silverlight para desarrolladores

public class producto { public long ID_Producto { get; set; } public string Nombre { get; set; } public string Descripcion { get; set; } public decimal Precio { get; set; } public int Stock { get; set; } }

El siguiente paso es enlazar el evento click del botn a nuestro cdigo C#. Podemos hacerlo con facilidad desde el cdigo XAML de nuestra aplicacin, si escribimos el nombre del evento en el botn y dejamos que Visual Studio complete el cdigo cuando presionamos la tecla TAB, como podemos ver en la siguiente figura.
71

3. EL MEJOR TRABAJO, CON LA MEJOR HERRAMIENTA

Una vez generado el evento, el cdigo XAML se ver de la siguiente manera:


Button Grid.Row=0 Grid.Column=1 Width=100 HorizontalAlignment=Right Margin=0,5,5,5 Content=Buscar x:Name=Button1 Click=Button1_Click></Button>

Y el cdigo C# de nuestra aplicacin tendr el siguiente aspecto:


public partial class Page : UserControl { public Page() { InitializeComponent(); } private void Button1_Click(object sender, RoutedEventArgs e) { } }

La funcin Button1_Click se ejecutar cada vez que el usuario presione el botn en la interfaz. Por tal motivo, deberemos agregar la lgica de bsqueda dentro de esta funcin. Pero, antes de realizar esta lgica, es necesario contar con los datos sobre los cuales trabajaremos. Para esto, crearemos una lista genrica de productos y la cargaremos con datos suficientes para poder hacer bsquedas sobre ellos. La carga de la lista podremos dispararla desde una funcin privada que ser llamada una nica vez cuando la aplicacin se cargue en primera instancia. Esto podemos lograrlo llamando el llenado de la lista desde la funcin Page en nuestro cdigo similar al siguiente:

RRR

EVENTOS

Todos los controles en Silverlight poseen una serie de eventos. Estos eventos representan simulaciones de acciones reales en la interfaz grfica. El clic del ratn, una tecla presionada, el conteo de un reloj son reacciones a cuestiones cotidianas de las aplicaciones. A estas reacciones, las llamamos eventos.

72

Silverlight para desarrolladores

public Page() { InitializeComponent(); CargarLista(); } private List<producto> productos; private void CargarLista() { //Inicializamos la lista de productos productos = new List<producto>(); //Cargamos la lista de productos con productos productos.Add(new producto() { ID_Producto = 1, Nombre = PC Bsica, Descripcion = PC de escritorio bsica, Precio = 1500, Stock = 10 }); productos.Add(new producto() { ID_Producto = 2, Nombre = PC Superior, Descripcion = PC de escritorio superior, Precio = 3500, Stock = 50 }); productos.Add(new producto() { ID_Producto = 3, Nombre = PC Notebook, Descripcion = PC tipo Notebook, Precio = 2500, Stock = 40 });

73

3. EL MEJOR TRABAJO, CON LA MEJOR HERRAMIENTA

productos.Add(new producto() { ID_Producto = 4, Nombre = PC NetBook, Descripcion = PC tipo NetBook, Precio = 2000, Stock = 450 }); productos.Add(new producto() { ID_Producto = 5, Nombre = SmartPhone, Descripcion = Telfono SmartPhone, Precio = 500, Stock = 55 }); }

Una vez cargados los elementos en la lista, slo nos queda realizar la bsqueda sobre la base de las entradas del usuario. Para acelerar las consultas, usaremos LinQ sobre colecciones. La funcin enlazada al evento click del botn deber tener un aspecto similar al siguiente:
private void Button1_Click(object sender, RoutedEventArgs e) { IEnumerable<producto> q = from c in productos where c.Nombre.Contains(this.txtBusqueda.Text) || c.Descripcion.Contains(this.txtBusqueda.Text) select c; this.GrillaDeProductos.ItemsSource = q; }

Si usamos la lista genrica productos, realizamos una consulta donde la clusula where restringe la bsqueda a todos los registros donde el nombre o la descripcin del producto concuerden con lo introducido por el usuario, en su totalidad o slo en una parte. El equivalente a esto en T-SQL sera mediante el uso de: Nombre like %DATO DEL USUARIO% OR Descripcion like %DATO DEL USUARIO%.
74

Silverlight para desarrolladores

Por ltimo, seleccionamos los valores resultantes de la bsqueda y se le asignan a la variable q, que ser asignada a la propiedad ItemsSource del DataGrid para que lo tome como su fuente de datos.

Figura 15. Nuestra aplicacin muestra los datos filtrados por la palabra clave introducida por el usuario.

Podemos extender la funcionalidad de nuestra aplicacin y del componente DataGrid si agregamos algunas propiedades. Este control es lo suficientemente verstil como para permitir modificar su apariencia y su comportamiento. A continuacin, agregamos la capacidad de que el usuario pueda reordenar las columnas de la grilla de resultados, y adems le asignamos colores al fondo de cada uno de los tems desplegados:
<data:DataGrid Grid.Row=1 Grid.Column=0 x:Name=GrillaDeProductos Grid.ColumnSpan=2 AutoGenerateColumns=True CanUserReorderColumns=True CanUserResizeColumns=False AlternatingRowBackground=LightBlue RowBackground=LightGreen> </data:DataGrid>

Las propiedades CanUserReorderColumns y CanUserResizeColumns permiten que el usuario mezcle las columnas arrastrndolas y soltndolas, y que pueda o no redimensionar el tamao de las columnas. Para especificar los colores de las filas, usamos RowBackground, que asignar el color de fondo para la fila, y Alternating RowBackground, que configurar el color de fondo de las filas alternativas (por cada fila par, usar este color en lugar del configurado en RowBackground).
75

3. EL MEJOR TRABAJO, CON LA MEJOR HERRAMIENTA

Figura 16. La imagen muestra cmo el usuario puede reordenar las columnas una vez activada la propiedad.

Interoperabilidad con Expression Blend 2


Si bien dijimos que el desarrollador de software debe enfocarse en las lneas de cdigo y en la resolucin del dominio del problema, existirn oportunidades en las que necesite hacer modificaciones en la interfaz visual o, en casos extremos, crearla por su cuenta. En este captulo, pudimos ver que Visual Studio 2008 por s solo no resulta tan verstil como es necesario en cuanto a diseo visual de aplicaciones Silverlight. Slo tenemos una vista previa de lo que diseamos en XAML, por lo que nos demanda un conocimiento avanzado sobre la descripcin de cada control y cada componente, sus jerarquas, atributos y composiciones. Esto, hasta no conseguir suficiente experiencia, podra transformarse en una situacin un tanto frustrante. Por ello, es recomendable tener instaladas las dos herramientas, aunque slo nos dediquemos a una de las ramas del desarrollo del producto. Si lo hacemos, podremos abrir el proyecto en el que estemos trabajando con Expression Blend 2 para su edicin sin la necesidad de cerrar la solucin o abrirla de manera externa. Si queremos editar nuestro proyecto

RRR

EXPRESSION BLEND 2

Es recomendable que siempre tengamos instalado Expression Blend 2 en nuestro equipo cuando desarrollemos aplicaciones Silverlight. Sin importar si slo nos dedicamos a la produccin de cdigo, esta herramienta nos ayudar a acelerar la produccin de cdigo XAML y nos facilitar la creacin de contenido visual.

76

Silverlight para desarrolladores

con Expression Blend 2, lo nico que necesitamos es seleccionar la pgina XAML por editar y, con el botn secundario del mouse, pulsar Abrir en Expression Blend.

Figura 17. Con el botn secundario del ratn, es posible abrir nuestro proyecto en Expression Blend 2.

Expression Blend 2 cargar el proyecto representndolo en su rbol de soluciones. Las modificaciones que hagamos en esta solucin se vern reflejadas, de forma automtica, en Visual Studio 2008. En la figura siguiente, se observa, a la derecha, el rbol de la solucin y, a la izquierda, la lista de controles presentes en el proyecto. Editar las propiedades visuales puede resultar ms simple desde aqu que desde Visual Studio 2008.

Figura 18. A la derecha, el rbol de la solucin representado de igual manera que en Visual Studio 2008.
77

3. EL MEJOR TRABAJO, CON LA MEJOR HERRAMIENTA

Para completar el ejemplo, modificaremos la apariencia del componente DataGrid. Primero lo seleccionamos en la lista de controles y luego, en la pestaa Propiedades, modificamos los colores usados para cada uno de los registros, as como el fondo.

Figura 19. Una vez que seleccionamos el DataGrid, modificamos sus propiedades en la pestaa Propiedades.

Podramos ejecutar la aplicacin desde Expression Blend 2 para ver sus resultados, aunque en este caso, una vez guardados los cambios, cerraremos esta aplicacin y volveremos a Visual Studio 2008. Si ste ha detectado cambios en el XAML, nos pedir autorizacin para recargar el contenido. En este caso, aceptaremos las modificaciones ya que representan los cambios realizados. Una vez que la aplicacin haya sido recargada, depuramos el cdigo presionando la tecla F5. Luego, si inspeccionamos el cdigo XAML del DataGrid generado por Expression Blend 2, notaremos cambios:
<data:DataGrid Grid.Row=1 Grid.Column=0 x:Name=GrillaDeProductos Grid.ColumnSpan=2 AutoGenerateColumns=True CanUserReorderColumns=True CanUserResizeColumns=False> <data:DataGrid.Background> <LinearGradientBrush EndPoint=0.5,1 StartPoint=0.5,0> <GradientStop Color=#FF462BEE/> <GradientStop Color=#FFE1E0EA Offset=1/> </LinearGradientBrush> </data:DataGrid.Background> <data:DataGrid.RowBackground>

78

Silverlight para desarrolladores

<LinearGradientBrush EndPoint=0.5,1 StartPoint=0.5,0> <GradientStop Color=#FF92B6C7/> <GradientStop Color=#FF51BFF0 Offset=1/> </LinearGradientBrush> </data:DataGrid.RowBackground> <data:DataGrid.AlternatingRowBackground> <LinearGradientBrush EndPoint=0.5,1 StartPoint=0.5,0> <GradientStop Color=#FF657446/> <GradientStop Color=#FFE0F2BA Offset=1/> </LinearGradientBrush> </data:DataGrid.AlternatingRowBackground> </data:DataGrid>

Figura 20. Nuevo aspecto visual del DataGrid basado en las modificaciones realizadas en Expression Blend 2.

RESUMEN
Visual Studio 2008 brinda al desarrollador elementos para acelerar la produccin de cdigo, as como tambin controles y componentes exclusivos para la resolucin de problemas planteados en el proceso de produccin del software. Visual Studio 2008 tambin deja modificar la parte visual con herramientas externas como Expression Blend 2. Demuestra as su versatilidad en el desarrollo de software y permite compartir visiones entre el productor de las interfaces grficas y el desarrollador de funcionalidades.

79

 ACTIVIDADES
PREGUNTAS TERICAS
1 Por qu es importante colocar la versin correcta de Silverlight en la declaracin HTML del componente? 2 Qu es un SDK? 3 Es necesario instalar algn aditamento para Visual Studio 2008 antes de desarrollar con Silverlight 2? 3 Intente cambiar los colores utilizados pa4 Cul es la diferencia entre Expression Blend 2 y Visual Studio 2008? 5 Es posible adicionar referencias a servicios web en un proyecto Silverlight 2? 6 Cmo se denomina el mecanismo que proporciona ayuda en el momento de la escritura de cdigo? 5 Revise la documentacin sobre servicios 7 Contamos, en Visual Studio 2008, con soporte para escritura de cdigo XAML? 8 Entre qu opciones podremos elegir al crear un nuevo proyecto Silverlight 2? 9 Qu ensamblado .Net se referencia en el momento en el que el control DataGrid es adicionado a nuestro proyecto Silverlight 2? 10 Cul es la diferencia entre usar la propiedad AutoGenerateColumns y no usarla en el control DataGrid? web en la direccin http://msdn.microsoft. com/es-es para saber ms sobre este tema. 4 Si el cdigo HTML presentado en este captulo le result extrao, visite el sitio web de la W3C para aprender ms sobre esta tecnologa: www.w3.org/html. ra representar los elementos en el control DataGrid y, as, obtener un nuevo aspecto en la aplicacin.

EJERCICIOS PRCTICOS
1 Para saber ms sobre LinQ, ingrese en el sitio de MSDN (http://msdn.microsoft. com/es-es) y busque esta tecnologa. 2 Para poner en prctica LinQ, trate de modificar el ejemplo presentado en este captulo incorporando el precio dentro de los parmetros del filtro de bsqueda.

80

Silverlight

Captulo

XAML al extremo
Es necesario tener una referencia de cada uno de los controles y componentes propuestos por Silverlight. Cada uno de ellos, su declaracin, mtodos, eventos y uso sern tratados en este captulo, que servir como un manual que nos guiar y ayudar en la construccin de nuestras aplicaciones Silverlight.
El lenguaje XAML Qu es XAML? Declaracin de objetos Controles y componentes Controles contenedores y agrupadores Control Grid Control GridSplitter Control Canvas Control StackPanel Control ScrollViewer Control Border Controles de interaccin con el usuario Control Button Control CheckBox Control RadioButton Control HyperlinkButton Control Image Control ComboBox Control ListBox Control TextBlock Control TextBox Control PasswordBox Control DataGrid Control Calendar Control DatePicker Control ProgressBar Control Slider Resumen Actividades 82 82 82 83 84 84 89 92 95 98 101 103 103 106 110 113 114 117 124 126 127 130 132 139 147 148 152 153 154

SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com

4. XAML AL EXTREMO

EL LENGUAJE XAML
Hasta este momento, ya hemos hablado de Silverlight, su arquitectura, alcances y restricciones. Hemos usado dos de las principales herramientas para desarrollar con Silverlight, as como realizado algunos ejemplos iniciales para poder movernos con mayor soltura, adems de entender mejor esta tecnologa. Es momento, entonces, de hacer un recorrido ms exhaustivo sobre cada uno de los controles y componentes que podemos encontrar en Silverlight. En este captulo, veremos cada uno de los elementos representados con XAML provistos por Silverlight, sus propiedades y sus usos elementales desde C#. Esta parte del libro puede ser considerada como una referencia a los controles de Silverlight y XAML.

Qu es XAML?
XAML es un lenguaje declarativo que tiene su raz en el XML. Con XAML, es posible declarar objetos que representen una interfaz grfica comn entre diferentes plataformas. Uno de los problemas acarreado por las plataformas, ya sean de escritorio, webs, u otras, as como distintos sistemas operativos, Windows, Linux, etctera, consiste en la imposibilidad de compartir entre ellas los mismos elementos visuales que componen la interfaz. Un acercamiento a esta solucin es el HTML, aunque ste slo es aplicado a la Web, y no se pueden compartir los mismos elementos en aplicaciones de escritorio. XAML, entonces, une bajo el mismo lenguaje declarativo la posibilidad de utilizar una nica interfaz grfica en diferentes ambientes. En el caso de aplicaciones de escritorio bajo Windows, mediante WPF, y, en la Web, por medio de Silverlight. Es necesario tener cierto cuidado cuando escribimos XAML, ya que ste es sensible a maysculas y minsculas. Esto quiere decir que deberemos prestar mucha atencin cuando queramos usar cualquier control o componente en Silverlight, ya que un cambio de maysculas a de minsculas har que la aplicacin deje de funcionar.

Declaracin de objetos
Los objetos en XAML pueden ser declarados de diferentes formas. Pero, en cualquier caso, un tag inicial deber siempre ser cerrado al terminar de usarlo. Estos objetos suelen presentar dos formas tradicionales de declaracin.
<Objeto> </Objeto>

Es importante que notemos la diferencia entre el tag de apertura y el de cierre. Como vemos, para poder cerrar un objeto en XAML, es necesario utilizar los
82

Controles y componentes

caracteres </, por lo dems, el nombre del objeto de apertura y su sintaxis son idnticos. Esto quiere decir que se respetan las maysculas y minsculas. Tambin es posible, si el tag lo permite, su apertura y cierre en una sola lnea.
<Objeto />

En el caso anterior, el tag es abierto al comienzo y cerrado al final con los mismos caracteres (/>). Por otro lado, al ser un lenguaje basado en XML, con nodos y subnodos, si el modelo de objeto lo permite es posible declarar un elemento dentro de otro, lo que permitir crear elementos mucho ms ricos. Esto adicionar, adems, versatilidad y simpleza en el momento de tener que crear componentes ms complejos, como botones que presenten como fondo un video y no un color plano, o agregar casillas de verificacin a una lista desplegable. Podemos anidar uno o ms elementos de la siguiente forma.
<Canvas> <Button></Button> </Canvas>

CONTROLES Y COMPONENTES
A lo largo de los tres primeros captulos, nos hemos encontrado con algunos de los controles y componentes disponibles en Silverlight: controles contenedores de otros controles; controles utilizados para mostrar videos, imgenes o datos; as como controles que capturan el comportamiento del usuario sirvindonos de nexo entre ste y la aplicacin creada. Este comportamiento es iniciado, por lo general, con la ayuda de un evento. Alguno de estos eventos son comunes a todos los controles Silverlight y entre ellos podemos encontrar los siguientes:

_`

ARCHIVOS HTA

Un intento de acercar la conmutacin de la interfaz grfica entre plataformas fue la creada por Microsoft por medio de los archivos HTA (HTML Application). Aqu, archivos con tags HTML regulares podan ser ejecutados en Windows sin la necesidad explcita de un navegador web.

83

4. XAML AL EXTREMO

GotFocus: este evento se disparar cuando el control tome el foco de la accin. Puede ser usado cuando el usuario navega de un control a otro en nuestra aplicacin Silverlight, pulsando la tecla TAB o presionando con el ratn. IsEnabledChanged: si modificamos el estado del control, pasndolo de habilitado a no habilitado, este evento nos pondr en alerta sobre ese cambio. KeyDown: en este caso, si el usuario presiona una tecla cuando el control tiene el foco, el evento se disparar. KeyUp: accin contraria a la anterior. Este evento se disparar en el momento en el que la tecla sea liberada. Esto es, cuando el usuario dej de presionarla. LayoutUpdated: cada vez que exista una modificacin visual en el control, ya sea por adicin de otro control, movimiento de las barras de desplazamiento o cambio de tamao del control, este evento ser disparado. LostFocus: sta es la accin opuesta a GotFocus. En el momento en que el control pierda el foco, el evento nos pondr en alerta. SizeChanged: si el control se modifica en su tamao, este evento lo comunicar. Es importante tener presente estos eventos, ya que nos sern de utilidad en la implementacin de nuestro cdigo y en el comportamiento de la aplicacin. Si bien algunos eventos son comunes a todos los controles, la declaracin y el uso varan. Veamos entonces, uno a uno, los controles y lo componentes disponibles, su funcionalidad, su declaracin sintctica y cmo podemos interactuar con ellos desde nuestro cdigo.

Controles contenedores y agrupadores


Los siguientes controles forman parte de los usados para agrupar o contener otros controles. Estos controles se utilizan, en especial, para manipular la estructura de diseo de nuestra aplicacin. Con ellos, es posible colocar elementos en diferentes posiciones, mantenerlos en fijos o desplazarlos por la aplicacin como un todo.

Control Grid
El control Grid, o grilla en castellano, est pensado para la representacin de filas y columnas dentro del lienzo de dibujo de Silverlight. Debemos usar este control cuando necesitemos organizar, de forma estructurada, otros controles Silverlight, colocando dentro de cada celda de la grilla el o los controles adicionales. Pensemos en este control como si fuera una planilla de clculo o, para aquellos desarrolladores web, en el tag <Table>, con sus <TR> y <TD> usados en el HTML. La declaracin inicial de un control Grid es simple:
<Grid x:Name=[NombreDelControl]> </Grid>

84

Controles y componentes

El tag <Grid> marca el inicio del control Grid, y debe ser cerrado con su tag finalizador </Grid>. Todos los controles contenidos por el elemento Grid debern ser escritos entre estos dos tags. Es importante, pero no obligatorio, asignarle un nombre por medio del atributo x:Name al control Grid (deberemos hacerlo si necesitamos manipularlo en tiempo de ejecucin). Tenemos que declarar las filas y las columnas al inicio de nuestro control Grid, pudiendo especificar tantas filas y columnas como necesitemos:
<Grid x:Name=[NombreDelControl]> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> </Grid>

El tag <Grid.RowDefinitions> es el contenedor de la cantidad de filas que incluir el control, y debemos colocar dentro de los lmites de ste tantos tags <RowDefinition> como filas queramos tener. Por su parte, el tag </Grid.RowDefinitions> deber incluirse para marcar el cierre y contenido de las filas definidas. De igual manera, el tag <Grid.ColumnDefinitions> tiene un comportamiento similar a <Grid.RowDefinitions>, con la clara diferencia que enumera las columnas del control Grid. Debemos colocar tantos <ColumnDefinition> como columnas queramos tener en nuestra grilla. Al finalizar la lista, cerramos el tag por medio de </Grid.ColumnDefinitions>. En el cdigo anterior, nuestra grilla cuenta con dos filas y tres columnas. Con la estructura bsica de la grilla definida, es posible asignarles atributos a los tags para modificar su comportamiento. Los primeros atributos son los que especifican el ancho (Width) y el alto (Height), tanto sea de las columnas como de las filas:

RRR

UNA CELDA

Una celda, en un control del tipo Grid, se encuentra conformada por la unin de sus filas y de sus columnas. El resultado de unir estos dos elementos arrojar un espacio para colocar otros controles o una celda. Es necesario el par columna y fila para poder obtener esta celda.

85

4. XAML AL EXTREMO

<Grid.ColumnDefinitions> <ColumnDefinition Width=60/> <ColumnDefinition Width=50*/> <ColumnDefinition Width=20/> </Grid.ColumnDefinitions>

En la definicin anterior, cada columna posee un ancho especfico, cuyo valor es representado en pixeles. La segunda columna tiene un valor caracterstico representado por un * (asterisco); este signo representa un comodn y significa que la columna ocupar los pixeles indicados anteriormente ms todos los que se encuentran libres, no definidos por las dems columnas. Si tenemos una grilla que ocupa 400 pixeles de ancho, y contamos con una suma total de columnas, de acuerdo con el ejemplo anterior, de 130 pixeles, la segunda columna ocupar 50 pixeles ms 270 pixeles restantes. Esta caracterstica es importante cuando necesitamos mantener ciertas columnas estticas y otras que se adapten sobre la base del ancho del contenedor de nuestra aplicacin. Como ejemplo, podramos incrustar una aplicacin Silverlight, en una pgina web, que ocupe el 100% de su ancho. Esta pgina podra ser visitada por diferentes entornos con distintas resoluciones de pantalla, lo que hara que la pgina se adaptase, en ancho, a la configuracin del usuario, y lograra que nuestra aplicacin Silverlight tambin se adaptara a sta modificando dinmicamente las columnas que posean un asterisco. Podemos observar el resultado de las configuraciones de las columnas en la figura que vemos a continuacin.

Figura 1. En esta imagen, podemos ver un control Grid configurado usando Expression Blend 2.
86

Controles y componentes

Sobre las filas, es posible configurar el alto (Height) como en el siguiente cdigo:
<Grid.RowDefinitions> <RowDefinition Height=70*/> <RowDefinition Height=70/> </Grid.RowDefinitions>

Con caractersticas idnticas a las nombradas para las columnas, podremos usar el comodn * para modificar el alto de las filas de manera dinmica. Si no especificamos un valor para el alto y el ancho a nivel del tag de la grilla, sta asumir que debe ocupar la totalidad definida por el contenedor. Podremos modificar estos valores agregando en forma manual estos valores:
<Grid x:Name=[NombreDelControl] Width=200 Height=200> <Grid.RowDefinitions> <RowDefinition Height=70*/> <RowDefinition Height=70/> ... ...

Figura 2. Ancho y alto definidos usando Expression Blend 2.

ShowGridLines, Cursor, ToolTipService.ToolTip

son otros atributos que pueden ser usados a nivel del tag que representa la grilla. ShowGridLines puede contener dos valores: True (verdadero) o False (falso), y mostrar o no las lneas que definen el
87

4. XAML AL EXTREMO

contorno de la grilla, sus filas y columnas. Por su parte, Cursor configura el tipo de puntero de mouse que se va a mostrar cuando ste se pase por encima del control de grilla, pudiendo elegir entre Arrow (flecha), Eraser (borrador), Hand (mano), IBean (smbolo de escritura), None (sin icono), SizeNS (cambio de tamao norte/sur), SizeWE (cambio de tamao oeste/este), Stylus (punto de lpiz) y Wait (reloj de arena de espera). Por ltimo, ToolTipService.ToolTip permite mostrarle al usuario mensajes emergentes temporales cuando el mouse se posiciona durante determinado tiempo sobre el control de grilla. En el siguiente cdigo, se aplican todos los elementos mencionados:
<Grid x:Name=[NombreDelControl] ShowGridLines=True Cursor=Eraser ToolTipService.ToolTip=Mi grilla Width=200 Height=200> <Grid.RowDefinitions> <RowDefinition Height=70*/> <RowDefinition Height=70/> ... ...

El cdigo anterior deber mostrar las lneas que delimitan la grilla, un mensaje desplegable y un cursor con forma de borrador. Todo esto, lo podemos observar en la imagen que aparece a continuacin.

Figura 3. Control Grid configurado con propiedades para el cursor, lneas divisorias y mensaje emergente.
88

Controles y componentes

Es posible tambin especificar la posicin del control en relacin con el contenedor principal. La grilla se puede colocar en cualquiera de las esquinas del contenedor, as como en el centro, e incluso especificar que ocupe toda una franja, ya sea superior, inferior, izquierda o derecha de la aplicacin Silverlight.
<Grid x:Name=[NombreDelControl] ShowGridLines=True Cursor=Eraser ToolTipService.ToolTip=Mi grilla HorizontalAlignment=Stretch VerticalAlignment=Stretch> <Grid.RowDefinitions> <RowDefinition Height=70*/>

Los atributos HorizontalAlignment y VerticalAlignment hacen que se pueda especificar la distribucin de la grilla dentro del contenedor principal. Podremos usar las propiedades Left (izquierda), Center (centro), Right (derecha) y Stretch (estirado) para el atributo HorizontalAlignment. Las propiedades Top (arriba), Center (centro), Bottom (abajo) y Stretch (estirado) son vlidas para el atributo VerticalAlignment. Si los dos atributos fueran configurados con la propiedad Stretch, la grilla ocupara todo el espacio provisto por el contenedor principal, como vemos en la siguiente figura.

Figura 4. Nuestra grilla ocupa el espacio disponible de su contenedor.

Control GridSplitter
el control libremente. Para poder utilizarlo, en primer lugar, deberemos configurar una grilla que
89

GridSplitter no es un contenedor por s solo, sino que se conjuga con Grid para poder manipular las columnas de este control y desplazarlas

4. XAML AL EXTREMO

contenga dos o ms columnas, o dos o ms filas. GridSplitter utilizar una de estas filas o columnas para redimensionar las restantes en tiempo de ejecucin. Declaramos un control GridSplitter de la siguiente manera:
<basics:GridSplitter x:Name=[NombreDelControl] Grid.Row=[Indice de fila] Grid.Column=[Indice de columna]> </basics:GridSplitter>

Es necesario especificar la fila y la columna en la cual este control se posicionar. Es importante mencionar que esta fila y columna no deberan ser usadas por otro control una vez asociado el GridSplitter. El siguiente cdigo muestra la implementacin completa de una grilla con un GridSplitter:
<Grid x:Name=LayoutRoot Width=400 Height=300> <Grid.RowDefinitions> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition MinWidth=10 MaxWidth=200 /> <ColumnDefinition Width=10/> <ColumnDefinition/> </Grid.ColumnDefinitions> <basics:GridSplitter x:Name=miGridSplitter Grid.Row=0 Grid.Column=1 VerticalAlignment=Stretch HorizontalAlignment=Center Background=#FFDD7676 Width=5></basics:GridSplitter> </Grid>

Notemos que la primera columna de la grilla, definida por el tag <ColumnDefinition>, posee dos atributos: MinWidth y MaxWidth. Los valores de cada uno representan

RRR

CUBRIR PARTE DEL CONTENEDOR

Podemos intentar la configuracin del atributo HorizontalAlignment con el valor Stretch y el atributo VerticalAlignment con el valor Top. Con esta accin, haremos que la grilla ocupe toda la parte superior del contenedor, dejando espacio en la parte inferior.

90

Controles y componentes

los valores mnimos y mximos, en este orden, a los que podr encogerse o estirarse dicha columna por accin del control GridSplitter. En la figura siguiente, podemos ver estos elementos funcionando.

Figura 5. GridSplitter aplicado a una grilla con atributos MinWidth y MaxWidth aplicados en la columna.

En el ejemplo anterior, el control GridSplitter se visualiza y acciona de manera vertical. Podemos, por otro lado, aplicarlo de forma horizontal. Para lograr esto, tendremos que aplicar este control a las filas del control Grid y no a sus columnas:
<Grid x:Name=LayoutRoot Width=400 Height=300> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition Height=10/> <RowDefinition MaxHeight=200 MinHeight=10/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition MinWidth=10 MaxWidth=200 /> <ColumnDefinition Width=10/> <ColumnDefinition /> </Grid.ColumnDefinitions> <basics:GridSplitter x:Name=miGridSplitter Grid.Row=0 Grid.Column=1 VerticalAlignment=Stretch HorizontalAlignment=Center Background=#FFDD7676 Width=5></basics:GridSplitter>

91

4. XAML AL EXTREMO

<basics:GridSplitter x:Name=miGridSplitterHorizontal Grid.ColumnSpan=3 Grid.Row=1 Grid.Column=0 HorizontalAlignment=Stretch VerticalAlignment=Center Background=#FFDD7676 Height=5></basics:GridSplitter> </Grid>

El cdigo anterior realiza algunas variaciones para poder soportar un control GridSplitter de manera horizontal. En primer lugar, agregamos dos filas ms a la grilla. La fila que soportar el cambio de dimensiones tiene ahora dos atributos, MinHeight y MaxHeight, que representan el valor mnimo y mximo soportado por la fila cuando se modifique su altura. Otro cambio es la cantidad de columnas que ocupar el control GridSplitter, representado por el atributo Grid.ColumnSpan colocando una unidad por cada columna que se ocupar. El resultado se puede ver en la siguiente imagen.

Figura 6. En este caso, vemos dos controles GridSplitter trabajando sobre la misma grilla.

Control Canvas
El control Canvas es el ms simple de los contenedores. Su trabajo, como contenedor, es el de incluir otros controles sin una estructura especfica. El siguiente cdigo muestra la declaracin del control Canvas:
<Canvas x:Name=[NombreDelControl]> </Canvas>

92

Controles y componentes

El objetivo del control Canvas es el de poder agrupar, de forma simple, otros elementos Silverlight. De esta forma, alterando el comportamiento del control Canvas, podremos alterar el de todos los controles contenidos en l. Podemos aplicar una transformacin al control Canvas para distorsionarlo, como vemos a continuacin.

Figura 7. Aplicando una transformacin al control Canvas.

A continuacin, podemos ver el cdigo de la figura anterior:


<Canvas x:Name=[NombreDelControl] HorizontalAlignment=Stretch RenderTransformOrigin=0.5,0.5> <Canvas.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform AngleX=-9 AngleY=-5/> <RotateTransform/> <TranslateTransform/> </TransformGroup> </Canvas.RenderTransform>

El tag <Canvas.RenderTransform> especifica el inicio de las diferentes transformaciones que pueda sufrir un control. En este caso, mediante el uso del tag <SkewTransform>, se especifican los valores numricos de la distorsin. Hablaremos ms sobre transformaciones en el captulo 5. Podremos posicionar diferentes controles dentro del elemento Canvas por medio del atributo Canvas.Left (izquierda) y Canvas.Top (arriba). Estos dos atributos deben
93

4. XAML AL EXTREMO

ser especificados en el control contenido y configuran la posicin en pixeles contando desde la esquina superior izquierda del control Canvas. En el siguiente ejemplo, el control del botn se posicionar a 106 pixeles desde la izquierda extrema y 90 pixeles desde la parte superior.
<Button Height=37 Width=73 Canvas.Left=106 Canvas.Top=90 Content=Click Aqu/>

Es posible combinar diferentes controles contenedores. As podramos usar un control Grid como contenedor principal y, en sus celdas, agrupar otros controles mediante el uso del control Canvas. Como dijimos, al agrupar otros controles dentro de un mismo contenedor, todos los cambios realizados en ste afectarn los controles incluidos, por lo que podramos agruparlos para que queden ocultos y mostrarlos en conjunto y no individualmente. El siguiente cdigo XAML crea un control Grid con dos columnas y dos filas; coloca dos botones en las filas superiores y un control Canvas en la fila inferior, que contiene un texto.
<Grid x:Name=LayoutRoot Background=White> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Button Margin=46,41,69,69 Content=Ocultar x:Name=BtnOcultar Click=BtnOcultar_Click/> <Button Margin=46,41,69,69 Grid.Column=1 Content=Mostrar x:Name=BtnMostrar Click=BtnMostrar_Click/> <Canvas Grid.Row=1 x:Name=CanvasContenedor> <TextBlock Margin=46,66,46,50 Grid.Row=1 Text=Mensaje a mostrar TextWrapping=Wrap/> </Canvas> </Grid>

Como vemos en el cdigo anterior, los botones apuntan a dos eventos manejados por C#. Este cdigo oculta y muestra el control Canvas, ocultando y mostrando, a su vez, todos los controles contenidos por l.
94

Controles y componentes

private void BtnOcultar_Click(object sender, RoutedEventArgs e) { this.CanvasContenedor.Visibility = Visibility.Collapsed; } private void BtnMostrar_Click(object sender, RoutedEventArgs e) { this.CanvasContenedor.Visibility = Visibility.Visible; }

Podemos ver en la siguiente imagen cmo, al presionar el botn para ocultar el control Canvas, todo su contenido tambin se hace invisible.

Figura 8. Una vez presionado el botn Ocultar, el control Canvas se hace invisible junto con todos sus controles contenidos.

Control StackPanel
Es posible que necesitemos crear una pila de controles, esto es, una sucesin de controles Silverlight que ocupen todo el espacio designado para ste, tanto en ancho como en alto. Pensemos en controles apilados, uno arriba del otro o uno al lado del otro. Es posible conseguir esto mediante el control StackPanel. Por lo comn, usaremos el control StackPanel dentro de otros controles contenedores como vimos en el caso del control Canvas. Para declarar un control StackPanel, usaremos el siguiente cdigo:
<StackPanel x:Name=[NombreDelControl]> </StackPanel>

95

4. XAML AL EXTREMO

Al agregar nuevos controles dentro de StackPanel, no necesitaremos configurar atributos de posiciones debido a que stos seguirn el flujo establecido por el StackPanel. Este flujo puede ser horizontal o vertical; para el primer caso, usaremos el atributo Orientation con el valor Horizontal, como vemos a continuacin.

Figura 9. En este caso, tenemos un StackPanel como contenedor principal y con flujo horizontal.

En la siguiente figura, vemos cmo el flujo de los controles se muestra de manera vertical; es posible lograr esto cambiando el valor del atributo Orientation a Vertical.

Figura 10. Aqu, el StackPanel como contenedor principal, est establecido con flujo vertical.
96

Controles y componentes

Es importante resaltar que este atributo debe ser declarado dentro del tag StackPanel, como vemos en el cdigo que aparece a continuacin:
<StackPanel x:Name=[NombreDelControl] Orientation=[Vertical | Horizontal]>

Los contenedores, como su nombre lo indica y ya hemos visto, contienen otros controles. Dentro de esta caracterstica, se incluye la creacin dinmica de otros controles y la posterior adicin del control creado al contenedor. El siguiente cdigo crea un nuevo control y lo adiciona al control contenedor StackPanel:
<Grid x:Name=LayoutRoot Background=White> <Grid.RowDefinitions> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> </Grid.ColumnDefinitions> <StackPanel x:Name=StackContenedor> <Button Content=Nuevo Control Click=Button_Click/> </StackPanel> </Grid>

En el cdigo anterior, hemos agregado un control Grid con una fila y una columna. Dentro de la celda creada, un StackPanel y, dentro de ste, un botn. Este botn disparar un evento en C# con el siguiente cdigo:
private void Button_Click(object sender, RoutedEventArgs e) { TextBox textBox = new TextBox(); textBox.Text = Inserte texto aqu; this.StackContenedor.Children.Add(textBox); }

Cuando el usuario presiona el botn inicial, ste crear una nueva instancia de un control TextBox, le configurar un texto por mostrar y lo adicionar a la lista de controles contenidos por el StackPanel. Podemos ver el resultado de pulsar varias veces el botn en la figura de la siguiente pgina.
97

4. XAML AL EXTREMO

Figura 11. Diferentes controles creados de manera dinmica a partir de una accin del usuario.

Control ScrollViewer
El control ScrollViewer es un contenedor que tiene la capacidad de mostrar barras de desplazamientos, tanto verticales como horizontales, dependiendo de su contenido. Declaramos un control ScrollViewer de la siguiente forma:
<ScrollViewer x:Name=[NombreDelControl]> </ScrollViewer>

Podemos manipular la aparicin de las barras de desplazamiento dejando que stas se generen en forma automtica sobre la base del contenido, ocultarlas por completo o mostrarlas siempre. Para esto, deberemos interactuar con los atributos HorizontalScrollBarVisibility y VerticalScrollBarVisibility, pudiendo elegir como posibles valores entre Disabled, Auto, Hidden y Visible. A continuacin, vemos los valores soportados por los atributos HorizontalScrollBarVisibility y VerticalScrollBarVisibility: Disabled: esta propiedad har que, sin importar el contenido que tenga el control ScrollViewer, las barras de desplazamiento no se muestren. Auto: en este caso, la presencia de las barras depende del contenido. Si ste sobrepasa las dimensiones propuestas por el ScrollViewer, las barras de desplazamientos se mostrarn de manera automtica. De esta forma pueden estar visibles o no. Hidden: en este caso, la barra de desplazamiento no se mostrar, pero el contenido creado dentro del control ScrollViewer que exceda el tamao del contenedor tampoco ser visible. Esta propiedad es til cuando queramos sincronizar dos
98

Controles y componentes

ocultando las barras de desplazamiento de uno y dejando que la interaccin del usuario con el segundo ScrollViewer impacte en el primero con barras de desplazamiento escondidas. Visible: esta propiedad indica que las barras de desplazamiento se mostrarn, incluso, si el contenido del control ScrollViewer no excede su tamao. Podemos ver, en el siguiente cdigo, cmo configurar las barras de desplazamiento:
<ScrollViewer x:Name=[NombreDelControl] HorizontalScrollBarVisibility=[Disabled | Auto | Hidden | Visible] VerticalScrollBarVisibility=[Disabled | Auto | Hidden | Visible]> </ScrollViewer>

ScrollViewer,

La siguiente figura, muestra cmo se han implementado dos controles ScrollViewer, los cuales han sido sincronizados para que, sobre la base del contenido del segundo, el primero se desplace y presente el mismo estado. Cada control ScrollViewer se encuentra en una celda de una grilla y, a su vez, cada ScrollViewer posee un control StackPanel para contener otros controles.

Figura 12. Dos ScrollViewer sincronizados.

A continuacin, podemos ver el cdigo XAML que da vida a la figura anterior:


<Grid x:Name=LayoutRoot Background=White> <Grid.RowDefinitions>

99

4. XAML AL EXTREMO

<RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width=100/> <ColumnDefinition Width=150/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Button Content=Crear elementos VerticalAlignment=Top Click=Button_Click/> <ScrollViewer x:Name=Scroll1 Grid.Column=1 HorizontalScrollBarVisibility=Visible VerticalScrollBarVisibility=Hidden> <StackPanel x:Name=MiStackPanel> </StackPanel> </ScrollViewer> <ScrollViewer x:Name=Scroll2 Grid.Column=2 HorizontalScrollBarVisibility=Visible VerticalScrollBarVisibility=Visible LayoutUpdated=Scroll2_LayoutUpdated> <StackPanel x:Name=SegundoStackPanel> </StackPanel> </ScrollViewer> </Grid>

Notemos que tanto al botn como a uno de los controles ScrollViewer se les han agregado eventos. En el caso del botn, el cdigo crear controles de manera dinmica para ser agregados a los controles StackPanel que estn contenidos por los ScrollViewer. En el caso del control ScrollViewer, el evento actualizar la posicin de las barras de desplazamiento del primer ScrollViewer cada vez que ste se actualice. Podemos ver el cdigo C# a continuacin:
private void Button_Click(object sender, RoutedEventArgs e) { TextBox textBox = new TextBox(); textBox.Text = Nuevo control; this.MiStackPanel.Children.Add(textBox); TextBox textBox2 = new TextBox(); textBox2.Text = Nuevo TextBlock representando el TextBox;

100

Controles y componentes

this.SegundoStackPanel.Children.Add(textBox2); } private void Scroll2_LayoutUpdated(object sender, EventArgs e) { this.Scroll1.ScrollToVerticalOffset(this.Scroll2.VerticalOffset); }

Como vemos en la Figura 13, al agregar controles de manera dinmica, el control ScrollViewer de la derecha muestra una barra de desplazamiento vertical, pero el otro ScrollViewer no presenta barra de desplazamiento alguna a pesar de tener tantos elementos como el de la derecha. Al mover la barra de desplazamiento del ScrollViewer de la derecha, tambin se desplaza el otro.

Figura 13. A pesar de que uno contiene barras de desplazamiento visibles y el otro no, ambos ScrollViewer estn sincronizados.

Control Border
El control Border es el ms simple de los controles, aunque puede resultar extremadamente til. Como su nombre en ingls lo indica, el control Border (borde o contorno) marca un borde a lo que contiene. Ya lo hemos usado en el captulo 2 al crear un contorno para la pelcula en nuestro visor de videos. De cualquier manera, este control posee otros atributos que resultan tiles. Es posible asignarle un grosor a cada lado del borde, as como crear esquinas redondeadas. A continuacin podemos ver la declaracin de un control Border:
101

4. XAML AL EXTREMO

<Border x:Name=[NombreDelControl]> </Border>

Para asignar los valores al borde, usamos el atributo BorderThickness, empleando un valor numrico en pixeles correspondiente al borde izquierdo, superior, derecho e inferior, en ese orden, separado por comas. El atributo CornerRadius especifica el radio numrico de curvatura de las esquinas pudiendo determinar los valores para la esquina superior izquierda, superior derecha, inferior derecha e inferior izquierda, separados por comas. Veamos, a continuacin, un control Border configurado:
<Border BorderThickness=5,5,5,5 BorderBrush=#FFA76666 CornerRadius=10,10,0,0> </Border>

Figura 14. Control Border configurado con grosor de 5 pixeles y redondeado en las esquinas superiores.

SMBOLO DE CORCHETE

Los smbolos de corchetes usados en el cdigo de ejemplo representan elementos que deben ser reemplazados en el momento de la escritura del cdigo real. Debemos cambiar estos valores por aquellos que sean convenientes para la aplicacin que estemos realizando.

102

Controles y componentes

Controles de interaccin con el usuario


Los controles que veremos listados a continuacin son aquellos que presentan la posibilidad de interactuar con el usuario, en especial, para capturar datos y acciones que ste realice o para presentarle informacin. Como podemos imaginar, son los controles ms utilizados en cualquier interfaz.

Control Button
El control Button o botn es uno de los ms conocidos y, prcticamente, lo encontramos en todas las interfaces visuales. Posee como objetivo principal el de disparar acciones por parte del usuario. Su declaracin es intuitiva, como podemos ver en el cdigo que aparece a continuacin:
<Button x:Name=[NombreDelControl] Content=[Texto del Botn]> </Button>

El atributo Content hace referencia al texto que se mostrar en el interior del control. La funcin primordial del control Button es la de poder capturar el clic del mouse y as disparar un evento para que nuestra pieza de cdigo reaccione a ste. Podremos enlazar este evento a nuestro cdigo agregando el atributo Click a la descripcin del control ms el nombre de la funcin en nuestro cdigo C# que se utilizar para ejecutar el evento en cuestin.
<Button x:Name=[NombreDelControl] Content=[Texto del Botn] Click=[NombreDeFuncion] > </Button>

La funcin por utilizar debe seguir una firma o contener una serie de parmetros exactos; sin esta firma, el evento no podr ser enlazado en forma correcta.
private void [NombreDeFuncion](object sender, RoutedEventArgs e)

El elemento sender de tipo object contiene el objeto ejecutor del evento. Este parmetro es importante, ya que podramos tener asociados a la misma funcin diferentes eventos Click de distintos botones. En el siguiente cdigo, se crean tres controles del tipo Button desde nuestro cdigo, asociando cada uno de ellos a la misma funcin creada con anterioridad. Cada vez que se dispare el evento de cualquiera de los botones, se tomar ese texto, haciendo uso del objeto sender, para informar qu botn realiz la accin. Primero declaramos el cdigo XAML:
103

4. XAML AL EXTREMO

<Grid x:Name=LayoutRoot Background=White> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width=0.332*/> <ColumnDefinition Width=0.51*/> <ColumnDefinition Width=0.158*/> </Grid.ColumnDefinitions> <StackPanel x:Name=MiStackPanel> <Button Click=Button_Click Content=Botn XAML HorizontalContentAlignment=Center/> </StackPanel> <TextBlock x:Name=mensaje HorizontalAlignment=Stretch Margin=8,8,0,0 VerticalAlignment=Stretch Grid.Column=1 Text= TextWrapping=Wrap/> </Grid>

Luego, el cdigo que generar los botones y enlazar los eventos:


public partial class Page : UserControl { public Page() { InitializeComponent() CrearBotones(); } private void CrearBotones() { for (int i = 0; i < 3; i++) { Button boton = new Button(); boton.Click += new RoutedEventHandler(Button_Click); boton.Content = Botn + i.ToString(); this.MiStackPanel.Children.Add(boton); } }

104

Controles y componentes

private void Button_Click(object sender, RoutedEventArgs e) { this.mensaje.Text = Presionado: + ((Button)sender).Content; } }

Cada uno de los botones creado en la funcin CrearBotones() es adicionado a un control StackPanel, adems de asociar el evento Click a la funcin Button_Click(). En la siguiente figura, podemos ver cmo se han creado los botones y tambin el resultado que se muestra cuando se presiona cada botn.

Figura 15. Lista de controles creados en forma dinmica con eventos asociados.

El control Button tambin posee la capacidad de incluir, dentro de l, otros controles. ste es el caso en el cual podemos redefinir su formato por medio de un control Image. Si lo colocamos dentro del tag del control Button, podremos hacer que la cara visible sea igual a la imagen seleccionada.

RRR

CONTENEDORES

Cuando trabajamos con contenedores, debemos tener en cuenta que es posible colocar slo un contenedor por pgina Silverlight. Si bien se pueden anidar controles del tipo contenedor, solamente debe existir uno a nivel general, es decir, ubicado entre los tags <UserControl></UserControl>.

105

4. XAML AL EXTREMO

<Button x:Name=[NombreDelControl]> <Image Height=[Alto en pxeles] Width=[Ancho en pxeles] Source=[Nombre de la imgen]/> </Button>

En la siguiente figura, es posible ver el nuevo botn usando una imagen como cara visible. Cabe destacar que el comportamiento de eventos en el botn ser exactamente igual que un botn sin otro elemento anidado.

Figura 16. Un botn anidando una imagen.

Control CheckBox
Este control, conocido tambin como de casilla de verificacin, presenta, tpicamente, un cuadrado donde el usuario puede marcar o desmarcar la casilla. Para declarar un control CheckBox, podremos hacerlo de la siguiente forma:
<CheckBox x:Name=[NombreDelControl] Content=[Texto del CheckBox]> </CheckBox>

En este caso, el atributo Content mostrar el texto escrito al margen derecho de la casilla de verificacin. Este control posee los dos estados comunes para este tipo de controles, que pueden variar entre verificado y no verificado. Pero tambin es posible obtener con l un tercer estado para casos donde se requiera un estado parcialmente verificado o indeterminado. Para lograr esto, tendremos que hacer uso del atributo IsThreeState, colocando como valor True (verdadero).
106

Controles y componentes

<CheckBox Content=C# IsThreeState=True HorizontalContentAlignment=Left/>

Tambin es posible especificar que el control est en estado verificado por defecto, haciendo uso del atributo IsChecked con su valor igual a True.
<CheckBox Content=C# IsChecked=True HorizontalContentAlignment=Left/>

En la figura que aparece a continuacin, se muestra cmo los controles CheckBox presentan el comportamiento configurado en cada caso.

Figura 17. Un control CheckBox por cada opcin disponible.

Este control puede poseer cuatro eventos para disparar por cada uno de los estados. Click: este evento es disparado cuando el usuario presiona el control CheckBox con el botn del mouse. Checked: slo se disparar cuando el control pase al estado de verificado. Unchecked: en este caso, el evento ser ejecutado slo cuando el control pase de cualquier estado a no verificado. Indeterminate: si hemos configurado el atributo IsThreeState a verdadero, este evento se disparar cuando el control entre en el tercer estado de seleccin.
107

4. XAML AL EXTREMO

El siguiente cdigo XAML muestra todas las configuraciones posibles. En este caso, se han configurado eventos para el segundo control CheckBox:
<Grid x:Name=LayoutRoot Background=White> <StackPanel HorizontalAlignment=Stretch VerticalAlignment=Stretch> <TextBlock Text=En qu lenguaje programas? TextWrapping=Wrap/> <CheckBox Content=C# IsChecked=True HorizontalContentAlignment=Left/> <CheckBox Content=Visual Basic.Net IsThreeState=True HorizontalContentAlignment=Left Click=CheckBox_Click Checked=CheckBox_Checked Indeterminate=CheckBox_Indeterminate Unchecked=CheckBox_Unchecked/> <CheckBox Content=Java IsThreeState=True HorizontalContentAlignment=Left/> <TextBlock Text= TextWrapping=Wrap x:Name=mensaje/> </StackPanel> </Grid>

Para capturar los eventos, deberemos escribir el siguiente cdigo C#:


private void CheckBox_Click(object sender, RoutedEventArgs e) { } private void CheckBox_Checked(object sender, RoutedEventArgs e) { this.mensaje.Text = Usted usa Visual Basic.net; } private void CheckBox_Indeterminate(object sender, RoutedEventArgs e) { this.mensaje.Text = No est seguro si usa o no Visual Basic.net; }

108

Controles y componentes

private void CheckBox_Unchecked(object sender, RoutedEventArgs e) { this.mensaje.Text = Usted no usa Visual Basic.net; }

En el cdigo anterior, no hemos colocado lneas adicionales en el evento Click debido a que ste se disparar en todas las oportunidades que el usuario presione el control, sin importar el estado al cual pasar en cada clic. El resultado debera ser el siguiente:

Figura 18. Al pasar al estado indeterminado, es desplegado el mensaje correspondiente.

Si bien podemos usar los eventos para recuperar informacin de los controles, existirn casos donde estos eventos no sean necesarios, pero s conocer el estado de los controles por medio de nuestro cdigo. Para poder acceder al control, es necesario asignarle un nombre descriptivo.
<CheckBox Content=Visual Basic.Net IsThreeState=True HorizontalContentAlignment=Left Click=CheckBox_Click Checked=CheckBox_Checked Indeterminate=CheckBox_Indeterminate Unchecked=CheckBox_Unchecked x:Name=VBCheckBox/>

Una vez nombrado el control, podremos usar la propiedad IsChecked para accede al valor actual del elemento. Esta propiedad es un valor del tipo Verdadero/Falso que, adems, cuenta con el atributo Nulleable, lo que significa que puede mantener tres
109

4. XAML AL EXTREMO

estados, True (verdadero), False (falso) y Null (nulo). Estos tres valores representan los tres posibles estados del control, siendo verdadero para el estado verificado, falso para no verificado y nulo para indeterminado. Como se observa a continuacin, el estado del control CheckBox se escribe en la consola de depuracin.
System.Diagnostics.Debug.WriteLine(CheckBox verificado: + this.VBCheckBox.IsChecked.ToString());

Control RadioButton
El control RadioButton extiende la funcionalidad del control CheckBox antes visto. Si bien ste se presenta como una casilla de verificacin, el formato visual tradicional es de un crculo, donde puede ser seleccionado uno de stos en un grupo de controles similares. El control RadioButton tiene el objetivo de presentar opciones de manera grupal, donde el usuario pueda seleccionar una de ese grupo, a diferencia del CheckBox, donde el usuario puede seleccionar tantas opciones como crea conveniente. Podemos declarar un control RadioButton de la siguiente forma:
<RadioButton x:Name=[NombreDelControl] Content=[Texto del RadioButton]> </RadioButton>

Como hemos dicho, el objetivo de este control es el trabajo en conjunto con otros similares de manera grupal. Para lograr este efecto, es necesario especificar, para cada control RadioButton, el nombre del grupo al cual pertenece. Todos los controles RadioButton con el mismo grupo actuarn como una unidad, pasando del estado verificado a no verificado en forma automtica. Para configurar un grupo, deberemos usar el atributo GroupName, colocando el nombre del grupo correspondiente.
<Grid x:Name=LayoutRoot Background=White> <StackPanel> <TextBlock Text=Gnero:></TextBlock> <RadioButton Content=Masculino GroupName=Sexo/> <RadioButton Content=Femenido GroupName=Sexo/> </StackPanel> </Grid>

El cdigo anterior muestra cmo podemos agrupar dos controles RadioButton mediante el atributo GroupName. Si colocamos los dos controles dentro del mismo grupo, obtendremos el resultado de la figura en la pgina siguiente.
110

Controles y componentes

Figura 19. Controles RadioButton en un mismo grupo.

Es posible generar tantos grupos cono necesitemos. Cada conjunto de controles RadioButton trabajar de manera independiente. El siguiente cdigo extiende el anterior, agregando dos columnas a la grilla y generando un nuevo grupo de controles RadioButton en la segunda columna:
<Grid x:Name=LayoutRoot Background=White> <Grid.RowDefinitions> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <StackPanel> <TextBlock Text=Gnero:></TextBlock> <RadioButton Content=Masculino GroupName=Sexo/> <RadioButton Content=Femenido GroupName=Sexo/> </StackPanel> <StackPanel Grid.Column=1> <TextBlock Text=Edad:/> <RadioButton Content=Menor de 18 aos GroupName=Edad/> <RadioButton Content=Mayor de 18 aos GroupName=Edad/> </StackPanel> </Grid>

111

4. XAML AL EXTREMO

De esta forma, tenemos dos grupos, uno definido por el valor Sexo y otro por Edad. Al seleccionar cualquiera de los elementos de un grupo, stos trabajarn de manera independiente o en relacin con su grupo.

Figura 20. Dos grupos de RadioButton trabajando de manera independiente.

El control RadioButton, al igual que el control CheckBox, puede mostrarse verificado desde el inicio mediante el atributo IsChecked, configurando su valor a True (verdadero), como vemos a continuacin:
<RadioButton Content=Mayor de 18 aos GroupName=Edad IsChecked=true/>

Este control posee eventos similares al del control CheckBox. Es posible enlazar eventos a la accin de presionado del mouse y al cambio de su estado. Como las posibilidades del control RadioButton son ms limitadas que las del control CheckBox,

APRENDIENDO SOBRE UX
Dentro de la librera de recursos provista por Microsoft en la Web, podremos encontrar una seccin que hace referencia a la aplicacin de reglas, recomendaciones y otros elementos relacionados con el momento del desarrollo de aplicaciones para Windows. Para poder ingresar en este sitio, deberemos navegar a la siguiente direccin: http://msdn.microsoft.com/.

112

Controles y componentes

consideremos que no vamos a tener disponible el evento Indeterminate, as como la propiedad que da vida a esta capacidad. Podemos ver un ejemplo de los eventos disponibles para este control a continuacin:
<RadioButton Content=Mayor de 18 aos GroupName=Edad IsChecked=true Click=RadioButton_Click Checked=RadioButton_Checked x:Name=RadioButtonMayor18/>

El enlace de estos eventos en nuestro cdigo C#.


private void RadioButton_Click(object sender, RoutedEventArgs e) { System.Diagnostics.Debug.WriteLine(Mayor de 18 aos presionado); } private void RadioButton_Checked(object sender, RoutedEventArgs e) { System.Diagnostics.Debug.WriteLine(Estado del control: + this.RadioButtonMayor18.IsChecked.ToString()); }

Control HyperlinkButton
El control HyperlinkButton es uno de los controles ms simples de manipular. Su objetivo consiste en proveer de un enlace o vnculo para navegar desde nuestra aplicacin hacia otra direccin web. Teniendo en cuenta que las aplicaciones Silverlight son hospedadas por los navegadores web en un ambiente web, este control resulta fundamental en cualquier proyecto que llevemos a cabo. Cuenta con dos atributos primarios: Content, como en controles anteriores, es usado para desplegar el texto que mostrar el control; y NavigateUri contiene el valor de la URL o pgina adonde el navegador web se dirigir. A continuacin, veamos un ejemplo:

RRR

ESTADOS DE LAS VARIABLES

Un cambio significativo en los lenguajes de programacin basados en Microsoft.Net fue la incorporacin de un nuevo estado para los tipos de datos. Este tipo se denomina Nulleable, o tipo de dato con soporte de nulos, y hace que el dato nulo tambin sea considerado un valor.

113

4. XAML AL EXTREMO

<HyperlinkButton Content=Ir a RedUsers NavigateUri=http://www.redusers.com> </HyperlinkButton>

Control Image
El control Image presenta un comportamiento particular. Si bien es utilizado para desplegar imgenes en nuestras aplicaciones Silverlight, este control nos permite visualizar imgenes que estn contenidas tanto en nuestra aplicacin como en cualquier otra direccin web vlida. La diferencia de estas dos posibilidades radica en el tamao del archivo generado por nuestra aplicacin y qu cantidad de informacin estaremos dispuestos a transferir al cliente que la consuma. Pensemos que las imgenes adicionadas a nuestros proyectos Silverlight son empaquetadas dentro del archivo de aplicacin de Silverlight, y ste debe ser descargado por completo antes de poder ejecutarse. Como vemos en la figura que aparece debajo, el archivo logo.jpg es incluido en el proyecto para luego ser visualizado por el control Image desde el mismo archivo.

Figura 21. Podemos ver la imagen incluida en el proyecto, a la derecha, en el explorador de soluciones.

Al compilar el proyecto, Visual Studio 2008 generar un archivo que tendr la extensin XAP (eXtended Application Package). Este archivo es el resultado de nuestro proyecto, tanto del cdigo como de todas las imgenes incluidas dentro de l, por lo que, mientras ms imgenes agreguemos, este archivo crecer en tamao y, por ende, se deber descargar un archivo mayor en el cliente, que har ms lenta la ejecucin inicial de la aplicacin.
114

Controles y componentes

Figura 22. Archivo XAP creado en la compilacin de la aplicacin Silverlight.

Por lo dicho antes, es necesario encontrar un balance entre los archivos de imgenes que vamos a incluir dentro del proyecto y aquellos que deberemos consumir de manera dinmica desde otro recurso de red. Para declarar un control Image, podemos hacerlo con el siguiente cdigo:
<Image Source=[Nombre de la imagen | Ruta de acceso de la imagen]></Image>

Si agregamos la imagen a nuestra solucin, con slo colocar su nombre, podremos visualizarla dentro del control Image. Por el contrario, colocando la direccin web completa de la imagen por visualizar, el control Image la consumir desde su origen. Veamos ejemplos de ambas formas:
<Grid x:Name=LayoutRoot Background=White> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> </Grid.ColumnDefinitions>

115

4. XAML AL EXTREMO

<Image Source=logo.jpg></Image> <Image Source=http://www.redusers.com/wpcontent/themes/redusers/images/logo.jpg Grid.Row=1></Image> </Grid>

En el cdigo anterior, hemos colocado dos controles Image, uno que utiliza una imagen incluida en el mismo proyecto Silverlight y la segunda que consume la misma imagen desde su origen web. En la siguiente figura, podemos ver el resultado.

Figura 23. Arriba, la imagen tomada desde la solucin. Abajo, consumida desde su direccin web.

Este control tambin cuenta con un atributo llamado Stretch, que es utilizado para configurar el comportamiento de la imagen sobre la base del tamao elegido para el control Image. Los valores del atributo Stretch pueden ser los siguientes: None: este atributo no aplicar ningn cambio a la imagen contenida por el control Image y la mostrar en su tamao original, incluso, cortando partes de sta si es ms grande que su contenedor. Fill: sin importar el tamao original de la imagen, sta se ajustar al contenedor Image para ocupar o rellenar por completo el tamao del control. Esto puede causar la deformacin de la imagen. Uniform: al igual que Fill, esta propiedad rellenar todo el contenedor con la imagen, pero ajustndola sin deformarla. UniformToFill: este valor es la conjuncin de los dos anteriores. Ajusta la imagen para que llene por completo el contenedor sin deformarla.
116

Controles y componentes

<Grid x:Name=LayoutRoot Background=White> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Image Source=logo.jpg Stretch=None></Image> <Image Source=http://www.redusers.com/wpcontent/themes/redusers/images/logo.jpg Grid.Row=1 Stretch=Fill></Image> <Image Source=logo.jpg Grid.Column=1/> <Image Source=logo.jpg Grid.Column=1 Grid.Row=1 Stretch=UniformToFill/> </Grid>

Figura 24. Aplicando los cuatro modificadores posibles para el control Image.

Control ComboBox
El objetivo del control ComboBox es el de brindarle al usuario la posibilidad de elegir un elemento de entre un conjunto de elementos o lista de stos. Como todos los controles comnmente usados en el desarrollo de software, entre sus objetivos est el de optimizar las interfaces grficas para brindar una mejor experiencia al usuario. Parte de esta optimizacin radica en la capacidad de reducir los elementos o controles
117

4. XAML AL EXTREMO

presentados en pantalla tratando de no sobrecargar, en lo visual, al usuario. El control ComboBox puede presentar una gran cantidad de informacin en un espacio reducido. La declaracin del control ComboBox podemos verla a continuacin:
<ComboBox x:Name=[NombreDelControl]> </ComboBox>

Como el ComboBox representa una lista de elementos entre los que se debe elegir alguno, es necesario que agreguemos tantos elementos como necesitemos mostrar, entre los cuales el usuario seleccionar. Para hacer esto, deberemos incluir el tag <ComboBoxItem> dentro del tag representativo del control ComboBox.
<ComboBox VerticalAlignment=Top Margin=0,0,165,0 Height=38 Grid.Row=1> <ComboBoxItem Content=Item 1></ComboBoxItem> <ComboBoxItem Content=Item 2></ComboBoxItem> <ComboBoxItem Content=Item 3></ComboBoxItem> <ComboBoxItem Content=Item 4></ComboBoxItem> <ComboBoxItem Content=Item 5></ComboBoxItem> </ComboBox>

El cdigo anterior genera un control ComboBox con cinco elementos, que se mostrarn en una lista desplegable al momento de presionar sobre la flecha derecha del control.

Figura 25. ComboBox desplegado para seleccionar uno de los tems de la lista.
118

Controles y componentes

Una vez seleccionado un tem de la lista, es posible saber cul de los elementos listados es el que fue seleccionado. Esto es til para recolectar los valores elegidos por el usuario en la aplicacin. Para comprobar cul ha sido el elemento marcado, primero deberemos asignarle un nombre al control ComboBox ya que, de esta forma, lo accederemos desde nuestro cdigo. El siguiente cdigo XAML muestra cmo hacerlo:
<ComboBox x:Name=ComboBox1 VerticalAlignment=Top Margin=0,0,165,0 Height=38 Grid.Row=1> <ComboBoxItem Content=Item 1></ComboBoxItem> <ComboBoxItem Content=Item 2></ComboBoxItem> <ComboBoxItem Content=Item 3></ComboBoxItem> <ComboBoxItem Content=Item 4></ComboBoxItem> <ComboBoxItem Content=Item 5></ComboBoxItem> </ComboBox> <TextBlock x:Name=mensaje HorizontalAlignment=Left VerticalAlignment=Top TextWrapping=Wrap Grid.Row=1 Margin=0,42,0,0/> <Button HorizontalAlignment=Right Click=Button_Click VerticalAlignment=Top Content=Aceptar Grid.Row=1 Margin=0,0,84.808,0 Height=38 Width=76/>

Tambin hemos agregado un control Button y un control TextBlock, el mismo que hemos usado en otros ejemplos y del que hablaremos un poco ms adelante. Una vez hecho esto, pasaremos al cdigo C#, donde colocaremos la lgica que captura esta informacin dentro del mtodo disparado por el evento Click del botn.
private void Button_Click(object sender, RoutedEventArgs e) { this.mensaje.Text = ((ComboBoxItem)this.ComboBox1.SelectedItem).Content.ToString(); }

Por medio de la propiedad SelectedItem del control ComboBox, es posible obtener un objeto del tipo Object. Este objeto es la representacin del tipo de elemento seleccionado. En el cdigo de este ejemplo, habamos utilizado un elemento <ComboBoxItem> como tipo de objeto para cada tem del ComboBox. Por este motivo, el objeto devuelto por la propiedad SelectedItem ser, internamente, de este tipo, razn por la cual realizamos un Cast (Conversin) del tipo Object a un tipo ComboBoxItem, accediendo por ltimo a la propiedad Content, que almacena el valor de este elemento.
119

4. XAML AL EXTREMO

Figura 26. Una vez seleccionado el elemento, el valor de ste es mostrado en el control TextBlock.

Si bien podemos agregar tems por medio de la escritura de XAML como en el ejemplo anterior, es posible adicionar nuevos elementos desde nuestro cdigo. De la misma forma que con XAML, necesitamos crear un nuevo elemento ComboBoxItem, configurando sus propiedades y adicionndolo, en definitiva, al control ComboBox. A continuacin, vemos cmo hacerlo:
public void CargarCombo() { for (int i = 0; i < 10; i++) { this.ComboPorCodigo.Items.Add(new ComboBoxItem() { Content = Item + i.ToString() }); } }

SMBOLO PIPE

En el cdigo de ejemplo, el smbolo | (Pipe) presenta una condicin OR (Uno u otro). Este smbolo representa la posibilidad de elegir para las propiedades una u otra de las listadas. Como existen propiedades con ms de dos valores seleccionables, stos se encontrarn delimitados por tantos | como valores contenga.

120

Controles y componentes

El cdigo crear diez elementos ComboBoxItem, adicionndolos al control ComboBox. Podemos ver el resultado del despliegue de la lista de elementos en la siguiente imagen:

Figura 27. ComboBox desplegado con elementos creados en forma dinmica.

Contamos con una tercera forma de crear elementos para un control ComboBox. Esta forma es la de enlazado de datos. El enlazado de datos nos facilita la tarea de crear elementos por nuestra cuenta, al mismo tiempo que estos datos podran ser obtenidos al ejecutar una consulta a una base de datos, servicio web o cualquier otro que pudiera retornar una coleccin de elementos.
public void CargarComboEnlazado() { List<string> datos = new List<string>(); for (int i = 0; i < 10; i++) { datos.Add(Item + i.ToString()); } this.ComboEnlazado.ItemsSource = datos; }

En este ejemplo simple, en lugar de cargar directamente los elementos sobre el ComboBox por cada iteracin del ciclo, simulamos una coleccin de datos por medio de una lista genrica, asignando esta lista a la propiedad ItemsSource del control ComboBox. Esta asignacin disparar el llenado del control con sus elementos, pudiendo manipularlos como vemos en la siguiente figura.
121

4. XAML AL EXTREMO

Figura 28. El control ComboBox desplegado fue cargado por medio del enlazado de datos.

Como en otros controles, el ComboBox posee una serie de eventos para poder capturar determinadas acciones del usuario y disparar cdigo C#. Algunos de los principales eventos los encontramos en la siguiente lista: DropDownOpened: este evento es disparado cuando el usuario despliega la lista con todos los elementos posibles de seleccin. Puede resultar muy til para la carga de datos realizada de manera asncrona, hacindola slo en el momento en el que la lista desplegable es mostrada. DropDownClosed: este evento representa la accin inversa al DropDownOpened. Una vez el usuario seleccione un elemento y la lista se cierre, este evento ser disparado. SelectionChanged: cada vez que el usuario selecciona un nuevo elemento de la lista, ste pasa a ser el elemento seleccionado, cambiando de estado la seleccin, as como los ndices utilizados. Este evento es til cuando necesitamos cargar elementos sobre la base de la seleccin de un tem especfico. Para incluir el manejo de los eventos, podemos modificar el ComboBox como vemos en el cdigo que aparece a continuacin
<ComboBox x:Name=ComboEnlazado DropDownClosed=ComboEnlazado_DropDownClosed DropDownOpened=ComboEnlazado_DropDownOpened SelectionChanged=ComboEnlazado_SelectionChanged />

122

Controles y componentes

Cada mtodo definido en el cdigo XAML tambin deber estar presente en nuestro cdigo C#. Este cdigo mostrar los diferentes mensajes basados en la accin aplicada en el control ComboBox. Veamos:
private void ComboEnlazado_DropDownClosed(object sender, EventArgs e) { System.Diagnostics.Debug.WriteLine(Lista desplegable cerrada); } private void ComboEnlazado_DropDownOpened(object sender, EventArgs e) { System.Diagnostics.Debug.WriteLine(Lista desplegable abierta); } private void ComboEnlazado_SelectionChanged(object sender, SelectionChangedEventArgs e) { System.Diagnostics.Debug.WriteLine(Nuevo elemento seleccionado); }

En todo caso, el control ComboBox no se limita a las caractersticas que ya hemos visto. Este control es extremadamente verstil, pudiendo adicionar elementos de diferentes tipos a la lista desplegable. Esto quiere decir que no estamos limitados a mostrar tems de slo texto, sino que tendremos la capacidad de agregar elementos complejos como controles RadioButton, CheckBox, Image, entre otros. El siguiente cdigo XAML demuestra cmo es posible agregar otro tipo de elementos al control ComboBox:
<ComboBox> <ListBoxItem Content=Item 1/> <CheckBox Content=Item 2/> <ComboBoxItem Content=Item 3/> <RadioButton Content=Item 4/> <Image Source=http://www.redusers.com/wpcontent/themes/redusers/images/logo.jpg/> </ComboBox>

Como podemos ver en el cdigo anterior, el control ComboBox poseer varios elementos, entre los que encontraremos un CheckBox, un RadioButton y un control Image. En la Figura 29 podemos ver este ComboBox en pleno funcionamiento.
123

4. XAML AL EXTREMO

Figura 29. El ComboBox tiene elementos complejos dentro de sus elementos seleccionables.

Al seleccionar el tem del ComboBox, ste pasar a visualizarse como el elemento seleccionado, presentando el mismo comportamiento que otros elementos, con la diferencia de que, al ser un elemento compuesto, ste tambin poseer las caractersticas de complejidad del control utilizado. En la Figura 30, el tem representado por un control CheckBox tambin incluye la funcionalidad de utilizar la casilla de verificacin.

Figura 30. Un control CheckBox como elemento de un control ComboBox.

Control ListBox
El control ListBox es homnimo del control ComboBox que ya vimos. La diferencia de este control es su capacidad de mostrar la lista de elementos no en una lista desplega124

Controles y componentes

ble, sino de manera constante, utilizando una barra de desplazamiento para movernos a travs de la lista. Para crear un control ListBox, usamos la siguiente sintaxis:
<ListBox x:Name=[NombreDelControl]> </ListBox>

Como el control ListBox posee el mismo comportamiento que el ComboBox, es posible incluir los mismos elementos complejos, as como elementos simples dentro de la lista de tems por mostrar y posibles de seleccin.
<ListBox VerticalAlignment=Top Height=94> <ListBoxItem Content=Item 1/> <ListBoxItem Content=Item 2/> <RadioButton Content=Masculino GroupName=Sexo/> <RadioButton Content=Femenino GroupName=Sexo/> <Image Source=http://www.redusers.com/wpcontent/themes/redusers/images/logo.jpg></Image> </ListBox>

El cdigo anterior muestra cinco elementos entre los cuales podemos encontrar un grupo de controles RadioButton y un control Image. El atributo Height (alto) es usado como el condicionante para, adems de configurar la altura del control, poder indicar cuntos elementos debern ser mostrados en la lista inicial.

Figura 31. ListBox con elementos complejos.


125

4. XAML AL EXTREMO

Como hemos comentado, este control podra considerarse una extensin del control ComboBox, por lo que la forma de manipularlo por cdigo, recolectar el elemento seleccionado, cargar nuevos elementos e interactuar con los eventos resulta similar. nicamente encontraremos una diferencia en la cantidad de eventos disponibles. Debido a que este control no posee una lista desplegable, los dos eventos correspondientes al accionar de la lista no estarn disponibles para su uso, por lo que slo podremos usar el evento SelectionChanged, que se disparar cada vez que se accione un nuevo elemento.

Control TextBlock
El control TextBlock es, sin dudas, el ms simple de los controles, incluso ms sencillo que el control HyperlinkButton visto en pginas anteriores. El control TextBlock cumple la funcin de mostrar un texto en nuestra aplicacin. Este control es til en especial para mostrar textos informativos al usuario, as como para complementarlo con otros controles o en la creacin de nuevos controles que requieran desplegar textos. La declaracin de este control se reduce a las siguientes lneas de cdigo:
<TextBlock x:Name=[NombreDelControl] Text=[Texto a visualizar]> </TextBlock>

Necesitaremos de un nombre para poder utilizarlo en nuestro cdigo. Podremos manipular la informacin desplegada por este control mediante el atributo Text (texto), configurndolo en el cdigo XAML o mediante cdigo de forma dinmica. El acceso desde nuestro cdigo resulta bastante sencillo, como se muestra a continuacin:
public void MostrarMensaje() { this.MiTextBlock.Text = Mensaje de bienvenida; }

El atributo Text usado en el cdigo XAML es el mismo que se transforma en la propiedad Text en nuestro cdigo, el mismo que usaremos para asignar o recolectar valores desde el control. Como todo componente para desplegar textos, es necesario que posea la capacidad de darle formato a ese texto, permitiendo variar su color, tipo y tamao de fuente, entre otras opciones. En el siguiente ejemplo, adicionamos algunas propiedades al control TextBlock para cambiar el tamao, color y tipo de fuente usada.
<TextBlock x:Name=MiTextBlock Text= FontFamily=Comic Sans MS FontSize=18 FontWeight=Bold>

126

Controles y componentes

<TextBlock.Foreground> <LinearGradientBrush EndPoint=0.5,1 StartPoint=0.5,0> <GradientStop Color=#FFEEE659/> <GradientStop Color=#FF1120A2 Offset=1/> </LinearGradientBrush> </TextBlock.Foreground> </TextBlock>

Para este caso, agregamos los atributos FontFamily, FontSize y FontWeight. Estos atributos son utilizados para configurar el tipo de fuente, su tamao y sus modificadores como, por ejemplo, Bold (negrita), Normal y otros. Tambin hemos agregado ms elementos para modificar el color de la fuente, usando un color degradado (hablaremos ms de este tema en los siguientes captulos).

Figura 32. TextBlock con un tipo de fuente diferente de la configurada por defecto.

Control TextBox
Al igual que el control anterior, el control TextBox es uno de los ms comunes en el desarrollo de aplicaciones, y ya lo hemos usado en varios de los ejemplos a travs de los captulos de este libro. Este control es el control bsico para introduccin de texto por parte del usuario, permitindole escribir texto libremente para que sea procesado por nuestra aplicacin. Este control posee una declaracin XAML muy simple:
<TextBox x:Name=[NombreDelControl] Text=[Texto a visualizar]> </TextBox>

127

4. XAML AL EXTREMO

En el control TextBox es posible especificar el comportamiento que tendr el flujo del texto escrito. Por ejemplo, si tenemos un control TextBox con un tamao en alto mayor a ms de una lnea de texto, es posible usar el atributo TextWrapping para que, cuando el texto llegue al final de la caja de texto, contine en la siguiente lnea. Si omitimos esta propiedad o colocamos el valor del atributo igual a NoWrap, el texto seguir su flujo normal y los caracteres ms antiguos escritos desaparecern del rango visual, teniendo que desplazarnos con el teclado para poder volver a ver esa informacin.
<TextBox Text= TextWrapping=[Wrap | NoWrap]> </TextBox>

Figura 33. El TextBox superior utiliza la propiedad Wrap y el de abajo usa NoWrap.

Tambin podemos necesitar cajas de texto para introduccin de texto extenso. Estas cajas poseen un tamao mayor que las de una sola lnea y muestran una barra de desplazamiento hacia el margen derecho de la caja, permitindole al usuario desplazarse por el texto escrito. Para lograr esto, deberemos agrandar el tamao de la caja de texto tanto como creamos necesario y configurar el atributo VerticalScrollBarVisibility con el valor Visible. Esta accin mostrar la barra de desplazamiento de manera constante, sin importar si el texto escrito sobrepasa la capacidad de la caja de texto.
<TextBox Text= AcceptsReturn=True TextWrapping=Wrap Margin=8,8,53,68 VerticalScrollBarVisibility=Visible> </TextBox>

128

Controles y componentes

Otra propiedad que aparece en el cdigo es AcceptReturn (aceptar retornos de carros). Este atributo permite que, si el usuario presiona la tecla INTRO o ENTER, el control refleje esta accin y genere saltos de lnea. La Figura 34 muestra dos controles TextBox configurados con las propiedades antes listadas, donde el que se encuentra en la parte inferior aplica el atributo TextWrapping con el valor NoWrap, que al utilizarlo en combinacin con el atributo HorizontalScrollBarVisibility mostrar adems una barra de desplazamiento en la parte inferior del control TextBox, esperando que el usuario presione la tecla INTRO o ENTER como condicin para enviar el texto a la siguiente lnea.

Figura 34. Controles TextBox con la posibilidad de presentar barras de desplazamiento basadas en su contenido. <TextBox Text= AcceptsReturn=True TextWrapping=Wrap Margin=8,8,53,68 HorizontalScrollBarVisibility=Visible VerticalScrollBarVisibility=Visible> </TextBox> <TextBox Text= AcceptsReturn=True Grid.Column=0 Grid.Row=1 TextWrapping=NoWrap Margin=8,8,53,68 HorizontalScrollBarVisibility=Visible VerticalScrollBarVisibility=Visible> </TextBox>

La asignacin de informacin a estos controles, en especial los multilneas, suele presentar cierta complejidad cuando se trata de manipular, en nuestro cdigo, los
129

4. XAML AL EXTREMO

retornos de carro y asignarlos al control. En el cdigo siguiente, se utilizan los caracteres de escape de C# para poder lograr este efecto. Como vemos, utiliza el carcter de escape \n para conseguir asignar un retorno de carro en el texto enviado al control:
private void Button_Click(object sender, RoutedEventArgs e) { this.TextoMultilinea.Text = Texto largo multilnea con \nretornos de carro; }

Al igual que los dems controles en Silverlight, el control TextBox tambin posee eventos que se dispararn bajo determinadas acciones del usuario. El ms destacado es el evento TextChanged, que se disparar cada vez que el contenido del control (su texto) cambie de estado. Podemos declarar el evento de la siguiente manera:
<TextBox Margin=8,58,8,52 x:Name=TextBoxConEvento TextChanged=TextBox_TextChanged Grid.Column=1 Text= TextWrapping=NoWrap> </TextBox>

En el cdigo que hemos propuesto, el evento TextChanged es asociado al mtodo TextBox_TextChanged del cdigo C#. Este mtodo, entonces, se ejecutar tantas veces como el texto de la caja de texto se vea afectado por el usuario.
private void TextBox_TextChanged(object sender, TextChangedEventArgs e) { System.Diagnostics.Debug.WriteLine(this.TextBoxConEvento.Text); }

En este ejemplo, cada vez que el usuario modifique el texto, ste se escribir en la consola de depuracin de Visual Studio 2008.

Control PasswordBox
es un control que extiende la funcionalidad del control TextBox con el objetivo de brindarnos la posibilidad de manipular contraseas en nuestras aplicaciones. El control PasswordBox est diseado para representar todos los caracteres introducidos por el usuario por medio de una mscara, ocultando lo que ste escriba y mostrando cada carcter introducido por medio de un punto de color negro.
PasswordBox
130

Controles y componentes

Este control es muy til en aquellas aplicaciones donde el usuario deba introducir credenciales de validacin, ya que stas no deben ser mostradas a otros usuarios que pudieran estar mirando su pantalla en el momento de realizar esta accin. A continuacin, podemos ver el cdigo XAML para declarar este control:
<PasswordBox x:Name=[NombreDelControl] Password=[Contrasea a visualizar]> </PasswordBox>

Debido a que el control PasswordBox manejar contraseas, el atributo de asignacin y lectura del texto contenido se cambia por Password (contrasea). Si bien el carcter mostrado por defecto es el de un crculo negro, es posible modificar esto mediante el atributo PasswordChar, pudiendo aplicar cualquier otro carcter, que se usar por cada letra o nmero introducido por el usuario. El cdigo siguiente muestra cmo configurar este atributo:
<PasswordBox PasswordChar=- /> </Password>

El carcter elegido en el cdigo anterior es el de un signo de resta, por lo que el control mostrar este elemento en lugar de los crculos de color negro tradicionales, como se observa en la siguiente figura.

Figura 35. Signos de resta en lugar de crculos en el patrn del control PasswordBox.
131

4. XAML AL EXTREMO

El control PasswordBox tambin posee eventos comunes utilizados por todos los controles, pero, al igual que el control TextBox, PasswordBox tiene un evento en particular para capturar la modificacin del estado del texto escrito en l. El evento en cuestin es PasswordChanged, y se comporta de igual forma que su homnimo TextChanged del control TextBox. Declaramos el evento PasswordChanged de la siguiente forma:
<PasswordBox PasswordChanged=PasswordBox_PasswordChanged PasswordChar=-> </PasswordBox>

Como mencionamos, para acceder al contenido escrito en el control PasswordBox, deberemos usar la propiedad Password como vemos en el siguiente ejemplo:
private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e) { System.Diagnostics.Debug.WriteLine(this.Password.Password); }

El cdigo propuesto anteriormente escribir cada cambio del control en la consola de depuracin de Visual Studio 2008.

Control DataGrid
En el captulo 3, hemos hecho uso del control DataGrid para mostrar informacin en forma de filas y columnas. Tambin vimos algunos atributos que permiten al usuario reordenar las columnas del control en tiempo de ejecucin, cambiar el tamao de las columnas y especificar diferentes colores para las filas mostradas. En este caso, iremos un poco ms lejos, y mostraremos otras caractersticas del control. Primero, recordemos cmo declarar el control DataGrid en XAML.
<data:DataGrid> </data:DataGrid>

Al agregar el control, podemos notar que Visual Studio sumar la referencia de System.Windows.Controls.Data a nuestra solucin. Adems, agregar una referencia en la cabecera de nuestro archivo para poder usar el control DataGrid.
<UserControl xmlns:data=clrnamespace:System.Windows.Controls;assembly=System.Windows.Controls.Data

132

Controles y componentes

ste es el motivo por el cual usamos <data:DataGrid> para declarar el control en nuestro cdigo. Podemos ver que el atributo xmlns genera una referencia al tipo data, indicndole desde dnde deber consumir estos componentes.

Figura 36. En el rbol de la solucin (arriba a la derecha), podemos ver que Visual Studio 2008 agreg la referencia a System.Windows.Controls.Data.

El control DataGrid tiene otras particularidades y, si bien en el ejemplo del captulo 3 este control cre las columnas sobre la base de los datos, es posible que necesitemos manipular de diferentes maneras la construccin de estas columnas. Podramos, por ejemplo, necesitar que en la edicin de una columna especfica, sta se comporte de una forma particular. Tambin podramos necesitar inmovilizar una columna para que sta no pueda variar su tamao por ms que el usuario as lo quiera. Para estas acciones, es posible utilizar Templates Columns (columnas plantilla). Estas columnas permiten personalizar por completo cada columna y adaptarla a nuestras necesidades. Veamos el siguiente cdigo:
<data:DataGrid AutoGenerateColumns=False x:Name=MiDataGrid> <data:DataGrid.Columns> <data:DataGridTemplateColumn Header=Fecha> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text={Binding FechaNacimiento}/> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> </data:DataGridTemplateColumn> </data:DataGrid.Columns> </data:DataGrid>

133

4. XAML AL EXTREMO

En el cdigo que aparece en la pgina anterior, podemos ver algunos nuevos tags usados para definir nuestras columnas. Veamos en detalle cada uno. <data:DataGrid.Columns>: este tag representa el contenedor para todas las columnas que crearemos por nuestra cuenta. <data:DataGridTemplateColumn>: representa una columna tipo plantilla. Sobre la base de esta plantilla, todas las filas bajo esta columna tendrn el aspecto definido por la plantilla. <data:DataGridTemplateColumn.CellTemplate>: este tag es el que representa el contenido de la celda de la plantilla. En l, podremos colocar otro control Silverlight, que ser usado para representar el dato de la fila en esa columna. {Binding Columna}: al momento de asignar una fuente de datos al DataGrid, todos los elementos que presenten el patrn {Binding} enlazarn los datos desde la fuente de datos y lo asignarn al atributo del control contenido por la plantilla. El nombre seguido de Binding representa el nombre de la columna en la fuente de datos. Podemos enlazar los datos desde una lista de entidades como la siguiente:
public class Personas { public string Nombre { get; set; } public string Apellido { get; set; }

RRR

CARACTERES DE ESCAPE

Los caracteres de escape son cdigos especiales para representar elementos que, tpicamente, no se pueden generar en cadenas de texto. Algunos de los caracteres ms usados son: \n para retornos de carro; \\ para agregar una barra invertida; \ para agregar una comilla doble; \ para agregar una comilla simple.

134

Controles y componentes

public DateTime FechaNacimiento { get; set; } public bool EnviarRegalo { get; set; } }

Podemos notar, en el cdigo anterior, que la propiedad FechaNacimiento es del tipo DateTime, as como EnviarRegalo es del tipo bool. Esto puede ser importante conocerlo ya que, segn el tipo de datos, podremos utilizar un control Silverlight especfico para representar el valor en el DataGrid. En la Figura 37, observamos cmo, al enlazar los datos, la nica columna mostrada es la definida anteriormente.

Figura 37. DataGrid mostrando una columna creada en forma manual.

Podemos crear y enlazar los datos con el siguiente cdigo.


public Page() {

135

4. XAML AL EXTREMO

InitializeComponent(); LlenarGrilla(); } private void LlenarGrilla() { List<Personas> personas = new List<Personas>(); for (int i = 0; i < 10; i++) { personas.Add(new Personas() { Nombre = Nombre + i.ToString(), Apellido = Apellido + i.ToString(), EnviarRegalo = ((i % 2) == 0 ? true : false), FechaNacimiento = DateTime.Now.AddDays(i)}); } this.MiDataGrid.ItemsSource = personas; }

Para mostrar la propiedad EnviarRegalo de la clase Personas, podramos, usar un control CheckBox, asociando el atributo IsChecked al valor de esta propiedad.
<data:DataGridTemplateColumn Header=Regalo> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <CheckBox IsEnabled=False IsChecked={Binding EnviarRegalo} ></CheckBox> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> </data:DataGridTemplateColumn>

RRR

COLUMNAS AUTOMTICAS

Es importante recordar que, si estamos trabajando con plantillas de columnas, debemos configurar el atributo AutoGenerateColumns con el valor False para que no se generen las columnas de forma automtica en el momento de enlazar los datos. Si olvidamos esto, las columnas se repetirn, y la informacin no ser consistente.

136

Controles y componentes

En este caso, la columna representar los valores de la fuente de datos en forma de control CheckBox como se ve en la figura que aparece a continuacin.

Figura 38. En este caso, se ha incorporado una nueva columna del tipo CheckBox para representar datos.

As como es posible crear nuestras propias columnas para mostrar la informacin, tambin podemos crear columnas con comportamiento para el momento de editarlas.
</data:DataGridTemplateColumn.CellTemplate> <data:DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <basics:DatePicker SelectedDate={Binding FechaNacimiento, Mode=TwoWay} /> </DataTemplate> </data:DataGridTemplateColumn.CellEditingTemplate> </data:DataGridTemplateColumn>

Mediante el cdigo anterior, es posible agregar una plantilla de columna para los casos en el que el usuario edite el contenido de la celda. Tambin hay que notar que esta columna <data:DataGridTemplateColumn.CellEditingTemplate> debe estar dentro del tag <data:DataGridTemplateColumn> y dentro del conjunto de la columna creada para asociar los datos en modo de vista que usamos al principio del ejemplo. En este caso, la columna de edicin es utilizada para mostrar un control DatePicker y as poder manejar la fecha de nacimiento de una manera ms prctica para el usuario, como se muestra en la Figura 39.
137

4. XAML AL EXTREMO

Figura 39. Un control DatePicker como plantilla para la edicin de la celda.

Otra caracterstica importante es la de poder congelar columnas para que stas no se vean afectadas por barras de desplazamiento. Pensemos en controles DataGrid con gran cantidad de columnas donde, para poder llegar hasta la ltima de stas, es necesario recorrer cada una mediante el uso de barras de desplazamiento. Existirn ocasiones en las que sea necesario seguir visualizando las primeras columnas por ms que nos desplacemos hasta el final del control DataGrid. Para lograr esto, deberemos usar el atributo FrozenColumnCount, asignando la cantidad de columnas que se van a congelar. Desde nuestro cdigo C#:
this.MiDataGrid.FrozenColumnCount = 1;

Como podemos ver en la Figura 40, la primera columna queda completamente inmvil y no se ve afectada por la barra de desplazamiento. Por defecto, cada columna tomar un tamao, pero tambin es posible, mediante cdigo, definir este comportamiento haciendo que las columnas del control DataGrid se adapten segn diferentes factores por medio del atributo Width de cada columna, asignando como posibles valores los que vemos a continuacin: Auto: al usar esta opcin, la columna ajustar su tamao en forma automtica. SizeToHeader: el tamao ser igual al largo del texto descriptivo de la columna. SizeToCells: en este caso, el tamao de la columna ser igual al tamao mximo contenido en cualquiera de las celdas de esta columna. Valor numrico: colocando slo un nmero, la columna ser tan ancha como el valor numrico asignado. Este valor numrico es equivalente a pixeles.
138

Controles y componentes

Figura 40. La columna que muestra la fecha de nacimiento de la persona est inmovilizada.

Control Calendar
El control Calendar nos permite manejar fechas de manera fcil. Por lo general, el manejo de fechas puede ser una tarea compleja, especialmente cuando necesitamos representar la misma fecha en diferentes idiomas. Para darnos una idea mediante un ejemplo simple, el patrn DD/MM/YYYY (da, mes, ao), utilizado casi siempre en pases de habla hispana, difiere del formato MM/DD/YYYY (mes, da, ao), utilizado en pases de habla inglesa. Este cambio, que a simple vista puede resultar trivial, a nivel de cdigo puede ocasionar severos dolores de cabeza para el desarrollador, ya que implica convertir fechas de un formato a otro sobre la base de las configuraciones del usuario. Como podemos imaginar, este problema puede acrecentarse an ms en ambientes de aplicaciones orientadas a la Web, debido a que stas pueden ser accedidas desde todos los pases del globo, donde cada usuario utiliza un formato de fechas diferente del nuestro. Imaginemos lo complejo que resultara tener que analizar en forma manual cada entrada de un usuario para poder saber la fecha exacta que quiso introducir. En el cdigo que aparece a continuacin vemos la declaracin de un control Calendar en XAML:
<basics:Calendar> </basics:Calendar>

Es necesario recordar que el prefijo basics: es tomado de la declaracin de los controles en la cabecera de nuestro archivo XAML. Esto indica que el control Calendar
139

4. XAML AL EXTREMO

tambin se encuentra incluido en la referencia System.Windows.Controls de las libreras de clases de Microsoft .Net para Silverlight.
<UserControl xmlns:basics=clrnamespace:System.Windows.Controls;assembly=System.Windows.Controls

El control Calendar posee varios atributos importantes que hacen a su configuracin, pudiendo variar la forma de presentar el calendario as como los tipos de seleccin de las fechas. Veamos a continuacin estos atributos y sus valores. DisplayMode Esta propiedad representa la forma en que ser mostrado el calendario y sus fechas, pudiendo optar por alguno de los siguientes valores: Month (mes): el calendario muestra todos los das correspondientes al mes seleccionado, permitiendo desplazarse de mes en mes y seleccionar uno o ms das. Year (ao): los elementos seleccionables del calendario sern los meses del ao elegido, pero no se pueden seleccionar das. Decade (dcada): muestra el calendario en formato de aos, desplegando un conjunto de aos sin meses ni das. Es posible seleccionar un ao o un rango de stos.

Figura 41. Control Calendar con los tres valores (Year, Decade y Month) posibles para el atributo DisplayMode.

SelectionMode El atributo SelectionMode (modo de seleccin) hace referencia a la forma en cmo el usuario podr seleccionar una fecha en el control Calendar. Este atributo puede tomar los valores que se listan a continuacin:
140

Controles y componentes

None: el usuario no podr seleccionar ninguna fecha del calendario. Esta opcin es ideal para mostrar el calendario para solo lectura. SingleDate: el usuario podr seleccionar una nica fecha del calendario. SingleRange: con esta opcin, el usuario podr seleccionar un rango de fechas, pero no podr concatenarlas con otros rangos o fechas individuales. MultiRange: esta seleccin de mltiples rangos de fechas permite al usuario seleccionar rangos de fechas en intervalos. El usuario puede usar la tecla CTRL y el botn del mouse para seleccionar ms de una fecha o un rango de stas.

Figura 42. En el calendario de la izquierda, podemos ver cmo se han podido seleccionar mltiples fechas y rangos de fechas.

Segn las configuraciones regionales de cada pas, es posible que necesitemos especificar el da que represente el inicio de la semana. Esto podemos lograrlo mediante el uso del atributo FirstDayOfWeek (primer da de la semana), pudiendo elegir cualquiera de los das incluidos en la semana mediante su nombre en ingls: Monday (lunes), Tuesday (martes), Wednesday (mircoles), Thursday (jueves), Friday (viernes), Saturday (sbado) y Sunday (domingo). El siguiente cdigo aplica los atributos vistos hasta el momento:
<basics:Calendar x:Name=MiCalendario DisplayMode=Year FirstDayOfWeek=Monday IsTodayHighlighted=True SelectionMode=MultipleRange> </basics:Calendar>

Este control tambin nos permite definir rangos de fechas que no puedan ser seleccionadas por el usuario. Esta accin suele ser usada en aplicaciones que necesiten mostrar das no laborales, fechas disponibles para la seleccin o fechas ya
141

4. XAML AL EXTREMO

seleccionadas que no deban ser utilizadas por el usuario. Para lograr esto, deberemos usar la propiedad BlackoutDates y asignar el rango de fechas por bloquear desde nuestro cdigo C#. En este caso, se mostrar el rango de fechas desde el 6 de junio de 2009 hasta el 15 de junio de 2009 como fechas no seleccionables,
public void ConfigurarCalendario() { this.MiCalendario.BlackoutDates.Add(new CalendarDateRange( new DateTime(2009, 6, 6), new DateTime(2009, 6, 15))); }

Figura 43. El calendario de la izquierda muestra un rango de fechas que no podrn ser seleccionadas.

Es posible agregar tantos rangos de fechas bloqueadas como necesitemos. Para esto ser necesario agregar tantos atributos BlackoutDates como rangos bloqueados necesitemos.
public void ConfigurarCalendario() { this.MiCalendario.BlackoutDates.Add(new CalendarDateRange( new DateTime(2009, 6, 6), new DateTime(2009, 6, 15))); this.MiCalendario.BlackoutDates.Add(new CalendarDateRange( new DateTime(2009, 6, 20), new DateTime(2009, 6, 28))); }

142

Controles y componentes

El cdigo muestra dos rangos de fechas bloqueadas dejando un pequeo rango de fechas posibles por seleccionar dentro de este rango.

Figura 44. Podemos ver dos rangos de fechas bloqueadas en el calendario de la izquierda.

Otra caracterstica del control Calendar es la posibilidad de especificar la fecha por mostrar, as como acotar el lmite de fechas que se van a mostrar a un rango determinado. Esto es til si necesitamos mostrarle al usuario una fecha especfica diferente de la fecha actual o si slo queremos darle la posibilidad de seleccionar una fecha dentro de un rango de fechas, pero sin bloquear las no seleccionables, como vimos antes. Para posicionar el calendario en una fecha especfica, deberemos usar, desde nuestro cdigo C#, la propiedad DisplayDate del calendario, que har que ste se posicione en esa fecha. Los rangos de fechas a los que el usuario tendr acceso podremos especificarlos con las propiedades DisplayDateStart y DisplayDateEnd.
this.CalendarioDerecha.DisplayDate = new DateTime(2009, 07, 1); this.CalendarioDerecha.DisplayDateStart = new DateTime(2009, 07, 1); this.CalendarioDerecha.DisplayDateEnd = new DateTime(2009, 07, 29);

RRR

MANTENERSE INFORMADO

Existe en la Web una infinidad de recursos sobre Silverlight, tanto cdigo de ejemplo como novedades sobre actualizaciones. Uno de los sitios que no podemos dejar de visitar es el de la biblioteca de clases Microsoft, que podemos encontrar en http://msdn.microsoft.com.

143

4. XAML AL EXTREMO

En el cdigo propuesto, el calendario mostrar como fecha el 1 de julio de 2009, limitando la seleccin de fechas a los rangos comprendidos entre la fecha anterior y el 29 de julio de 2009. En la Figura 45, podemos ver cmo este calendario muestra slo este rango como nica seleccin posible.

Figura 45. El calendario que se encuentra a la derecha muestra slo los valores especificados dentro del rango de fechas asignadas por cdigo.

Es posible tambin entregarle al usuario un calendario con fechas ya seleccionadas segn lo que establezcamos desde nuestro cdigo C#. Para esto, debemos usar las propiedades SelectedDate cuando queramos seleccionar una nica fecha, y SeletedDates cuando necesitemos seleccionar una o ms fechas. En el cdigo, podemos ver cmo se seleccionan fechas diferentes para generar una lnea de seleccin como se ve en la Figura 46, que aparece en la pagina siguiente.
this.MiCalendario.SelectedDate = DateTime.Now.AddDays(10); this.MiCalendario.SelectedDates.Add(DateTime.Now.AddDays(11)); this.MiCalendario.SelectedDates.Add(DateTime.Now.AddDays(12));

RRR

MODOS EN EDICIN

Cuando creamos plantillas para las columnas y, adems, incluimos plantillas de edicin de columnas, es importante asegurarnos de agregar el atributo Mode con el valor TwoWay (dos vas). Si no lo hacemos, podramos perder informacin, ya que la fuente de datos no se actualizara con la accin de edicin del usuario.

144

Controles y componentes

Figura 46. Adems de las fechas bloqueadas en el calendario de la izquierda, podemos ver un rango de fechas seleccionadas.

Estas mismas propiedades pueden ser usadas para recolectar la fecha seleccionada. Teniendo en cuenta que, para asignar el valor hemos usado un tipo DateTime, al recuperarlo obtendremos tambin un tipo DateTime. La ventaja de esto es que no deberemos preocuparnos por el formato de fecha usado por el usuario.
private void Button_Click(object sender, RoutedEventArgs e) { this.textoFecha.Text = Fecha seleccionada: + this.CalendarioDerecha.SelectedDate.ToString(); }

Figura 47. Al presionar el botn, ste muestra la fecha seleccionada en el calendario de la derecha.
145

4. XAML AL EXTREMO

Como utilizamos SelectedDates, pudimos agregar un rango de fechas seleccionadas, por lo que deberemos utilizar esta misma propiedad para obtener aquellas fechas seleccionadas. Esta propiedad es til cuando se conjuga con el uso del atributo SelectionMode, que ya hemos visto, porque, con l, podemos darle al usuario la posibilidad de especificar ms de una fecha; luego, necesitaremos algn mecanismo para poder capturar esas fechas. El cdigo siguiente no realiza ninguna accin en especial, pero muestra cmo es posible capturar todas las fechas seleccionadas y almacenarlas en una coleccin de fechas. En la Figura 48, observamos cmo, en modo de depuracin, inspeccionamos el resultado de la ejecucin del cdigo mostrando la lista de fechas seleccionadas.
private void Button_Click_1(object sender, RoutedEventArgs e) { Collection<DateTime> fechas = this.MiCalendario.SelectedDates; }

Figura 48. Al inspeccionar la variable fechas, sta nos muestra todas las fechas seleccionadas por el usuario en el control Calendar.

El control Calendar, al igual que los dems controles, posee eventos que nos avisarn de los cambios realizados por el usuario. Los tres eventos principales listados en el cdigo anterior son DisplayDateChanged, DisplayDatesChanged y DisplayModeChanged. Los dos primeros estn relacionados con la seleccin de fechas por parte del usuario: mientras que DisplayDateChanged se disparar cada vez que el usuario seleccione una nueva fecha, DisplayDatesChanged se disparar cuando el usuario modifique el rango de fechas seleccionadas. Por otro lado, DisplayModeChanged se disparar cuando el modo de presentacin del calendario (Month, Year, Decade) sea alterado.
146

Controles y componentes

<basics:Calendar DisplayDateChanged=Calendar_DisplayDateChanged DisplayModeChanged=Calendar_DisplayModeChanged SelectedDatesChanged=Calendar_SelectedDatesChanged DisplayMode=Decade/>

Control DatePicker
El control DatePicker es una extensin del control Calendar que vimos antes. Este control extiende la funcionalidad del calendario agregando una caja de texto para que el usuario pueda escribir en ella una fecha sin tener que navegar en el calendario para poder seleccionarla. Adems, este control suele ocupar menos espacio al desplegar el calendario cuando el icono de calendario a la derecha de la caja de texto es seleccionado, ocultndolo una vez que la fecha fue seleccionada. La declaracin es:
<basics:DatePicker> </basics:DatePicker>

Como este control es la unin de funcionalidades de un control Calendar y un control TextBox, las propiedades y eventos aplicados al control DatePicker son las mismas que las aplicadas al control Calendar. Podemos especificar fechas bloqueadas, da de inicio de la semana, fechas seleccionadas por defecto, as como reducir la cantidad de fechas navegables por el usuario. De igual forma, los eventos relacionados con este control pueden ser copiados de los eventos usados por el control Calendar. Este control agrega un nuevo atributo especfico: SelectedDateFormat, que permite configurar la forma en la que se mostrar la fecha seleccionada en la caja de texto. Las opciones son: Long: fecha en formato largo. La caja de texto mostrar la fecha usando el nombre del da y el nombre del mes seleccionado, generando una fecha larga. Short: fecha en formato corto. La caja de texto utilizar el formato corto numrico (dd/mm/yyyy) para mostrar la fecha seleccionada.

MANEJO DE FECHAS

Los formatos en los que se pueden expresar las fechas varan de acuerdo al pas del usuario. Por lo tanto, deberemos tener sumo cuidado al momento de manipular estos valores en aplicaciones que puedan ser consumidas desde diferentes ubicaciones en el mundo. Ms informacin en http://msdn.microsoft.com/es-es/.

147

4. XAML AL EXTREMO

Figura 49. Podemos ver el control DatePicker de la izquierda con formato de fecha larga y a la derecha con formato de fecha corta.

Control ProgressBar
El control ProgressBar (barra de progreso) representa, tpicamente, una lnea que puede mostrar el progreso evolutivo de una cosa. Es comn ver este tipo de controles en aplicaciones donde se cargan elementos de manera dinmica, mostrando el progreso de esta carga mediante una barra de progreso. La declaracin XAML es:
<ProgressBar> </ProgressBar>

Este control requiere de la configuracin de dos atributos para especificar el valor mnimo y el valor mximo aceptados para desplegar la barra interna de progreso. Minimum: este atributo representa el valor numrico mnimo que puede tomar la barra de progreso. Casi siempre, el valor es equivalente a 0 (cero). Maximum: el valor mximo permitido que obtendr la barra de progreso. Podemos colocar un valor tan elevado como fracciones internas queramos tener. Esto quiere decir que, si acumulamos valores para la barra de progreso avance de 10 en 10, y nuestro mximo es de 100, slo veremos 10 intervalos en la barra de progresos. Si usamos un valor mayor o valores menores acumulativos, la barra de progresos se desplazar con ms suavidad por tener un rango mayor de intervalos. Value: este atributo contiene el valor de la barra de progreso. Si asignamos un valor inicial diferente del valor mnimo establecido, la barra de progresos se mostrar con informacin de progreso inicializada.
148

Controles y componentes

Podemos asignar los valores de la siguiente forma:


<ProgressBar Minimum=0 Maximum=100 Value=50 x:Name=MiProgressBar> </ProgressBar>

Figura 50. ProgressBar con progreso configurado.

La propiedad Value es la que deberemos usar en nuestro cdigo para poder asignar, en tiempo de ejecucin, valores al control ProgressBar para que ste muestre el estado y el progreso de la accin realizada. Para entender este concepto, podemos simular un proceso de carga mediante la utilizacin de un cronmetro o Timer, y hacer que, por cada intervalo ejecutado por este cronmetro, el control ProgressBar avance su barra de progreso.
Storyboard _temporizador = new Storyboard(); public Page() { InitializeComponent(); _temporizador.Duration = TimeSpan.FromMilliseconds(10); _temporizador.Completed += new EventHandler(_temporizador_Completed); } private void _temporizador_Completed(object sender, EventArgs e) { if (this.MiProgressBar.Value < this.MiProgressBar.Maximum) {

149

4. XAML AL EXTREMO

this.MiProgressBar.Value += 1; _temporizador.Begin(); } } private void IniciarProgressBar() { this.MiProgressBar.Value = 0; _temporizador.Begin(); } private void Button_Click(object sender, RoutedEventArgs e) { IniciarProgressBar(); }

Por cada intervalo de temporizador, el valor del control ProgressBar es incrementado en 1; esta accin se repite hasta que el valor actual de la barra de progreso sea igual al valor mximo disponible en el control ProgressBar configurado por medio de la propiedad Maximum. Otro atributo til con el que cuenta el control ProgressBar es IsIndeterminate, que debemos utilizar cuando no sabemos con exactitud cules sern los valores del progreso por mostrar. Al configurar el atributo con el valor True (verdadero), el control mostrar un sinfn en la barra de progreso, que da a entender que se desconoce el estado actual de progreso.

Figura 51. A la derecha, el control ProgressBar con el atributo IsIndeterminate aplicado.


150

Controles y componentes

Tambin es posible utilizar nuestro propio patrn visual para mostrar como barra de progreso. Como vemos en la Figura 52 que aparece debajo, utilizamos una imagen como elemento de progreso y no un elemento de color plano. Si agregamos un objeto del tipo <ImageBrush> dentro del tag <ProgressBar.Foreground>, cambiamos el color slido de la barra de progreso por la imagen seleccionada.
<ProgressBar Grid.Row=1 Grid.Column=0 Minimum=0 Maximum=100 Value=60 Margin=8,42,8,76 d:LayoutOverrides=VerticalAlignment> <ProgressBar.Foreground> <ImageBrush ImageSource=http://www.redusers.com/wpcontent/themes/redusers/images/logo.jpg/> </ProgressBar.Foreground> </ProgressBar>

Figura 52. En este ejemplo, el control ProgressBar usa una imagen como patrn para la barra de progreso.

RRR

MODO DE DEPURACIN

Si bien hablamos de modos de ejecucin y compilacin, tambin existe el modo de depuracin. A este modo accedemos, por lo general, al presionar la tecla F5 en nuestra aplicacin. Este modo nos permitir movernos lnea a lnea por nuestro cdigo para poder depurarlo.

151

4. XAML AL EXTREMO

Control Slider
Slider es un control conocido por los desarrolladores de aplicaciones de escritorio. Puede ser considerado una especie de potencimetro, y al desplazar el medidor, el control informar el valor aplicado por el usuario. Podemos declararlo de la siguiente forma:
<Slider> </Slider>

Algunos atributos del control Slider son similares al del control ProgressBar, pero agrega otros especficos, que vemos a continuacin: Minimum: al igual que con el control ProgressBar, este atributo representa el mnimo valor posible que obtendr el control Slider. Maximum: equivale al valor mayor posible que podr obtener el control. SmallChange: cuando el usuario desplaza la barra del control Slider, este valor representar el intervalo mnimo de esta accin. As, si tenemos un valor equivalente a 1, el control se desplazar en intervalos pequeos. Con valores mayores, los saltos sern equivalentes a este valor. LargeChange: en el caso de que el usuario no utilice el botn para modificar el valor del control, sino que, por el contrario, presione sobre la barra del control Slider, esta accin har que el acumulador salte segn el valor especificado en esta propiedad. Orientation: el control Slider puede visualizarse de dos formas, de manera horizontal o vertical. Esta orientacin se define mediante los valores Horizontal y Vertical.
<Slider Minimum=0 Maximum=100 LargeChange=10 SmallChange=1 Orientation=Vertical> </Slider>

Suscribindonos al evento ValueChanged, ser posible disparar cdigo cada vez que el usuario modifique los valores del control. Tomaremos el valor actual del control Slider mediante la propiedad Value.
<Slider x:Name=MiSlider ValueChanged=Slider_ValueChanged Minimum=0 Maximum=100 LargeChange=10 SmallChange=1 Orientation=Vertical> </Slider>

152

Controles y componentes

Figura 53. En este ejemplo, el control Slider se presenta de manera vertical.

En nuestro cdigo C#, tomaremos este valor para mostrarlo en la aplicacin. Como resultado, cada vez que el usuario desplace la barra del control Slider, el control TextBlock tomar este valor y lo mostrar.
private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { this.textoSlider.Text = Valor del Slider: + this.MiSlider.Value.ToString(); }

RESUMEN
En este captulo hemos visto los controles nativos de Silverlight y cmo implementarlos por medio de cdigo XAML y desde C#. Si bien hemos podido interactuar con las principales propiedades de estos controles, an queda mucho por delante ya que es posible mezclarlos y combinarlos de diferentes formas para obtener mejores interfaces visuales. Este captulo es una gua de referencia sobre los controles Silverlight, y, en los captulos siguientes, utilizaremos lo que hemos visto aqu.

153

 ACTIVIDADES
PREGUNTAS TERICAS
1 XAML puede ser interpretado por sistemas no Microsoft? 2 Cul es el problema principal entre las interfaces para distintas plataformas? 3 Cmo ayuda el cdigo XAML en la posibilidad de transportar las interfaces entre distintas plataformas? 4 Cuntas maneras de cerrar elementos XAML existen? 5 En qu categoras podemos agrupar los controles XAML? 4 Ingrese en el sitio web de UXity (www. 6 Es posible tener ms de un control contenedor como raz del documento XAML? 7 Es posible que el usuario desplace las columnas y filas de un control Grid sin necesidad de generar cdigo? 8 Se pueden crear nuevos controles mediante la conjuncin de dos o ms controles XAML? 9 Qu contiene un archivo con extensin XAP? 10 Qu atributo en los controles contenedores de texto deberemos usar para obtener el valor introducido por el usuario? uxity.com) para obtener ejemplos y material sobre Silverlight en castellano. 5 Transforme un control HyperlinkButton para que ste sea una imagen y no un texto.

EJERCICIOS PRCTICOS
1 Cree dos grupos de controles RadioButton. Intente que cada grupo trabaje de forma independiente haciendo que la eleccin de un control en un grupo no afecte el elemento seleccionado en el segundo grupo. 2 Los controles pueden ser creados desde cdigo XAML. Intente crear un conjunto de controles, pero desde cdigo C#. 3 Habiendo agregado diferentes elementos dentro de un control contenedor, recorra cada uno de los elementos contenidos y modifique sus valores desde cdigo C#.

154

Silverlight

Captulo

Luz, cmara, accin


La forma de presentar la informacin no se reduce a colocar controles en posiciones especficas, sino a la habilidad de poder presentar esta informacin de la mejor manera y con el mayor dinamismo posible. En este captulo veremos cmo agregar el factor dinmico a nuestras aplicaciones, mediante el uso de animaciones y comportamientos.
Mover objetos Transformaciones Transformacin de traslacin Transformacin de rotacin Transformacin escalar Transformacin de distorsin Aplicar todas las transformaciones Animaciones DoubleAnimation ColorAnimation Animaciones y transformaciones Estilos y plantillas Estilos Plantillas Resumen Actividades 156 158 159 161 165 167 168 170 171 173 175 178 178 182 185 186

SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com

5. LUZ, CMARA, ACCIN

MOVER OBJETOS
En los captulos anteriores, hemos usado Silverlight para desplegar informacin desde fuentes de datos, permitiendo al usuario interactuar con stos. Podramos decir que, de alguna forma, hemos creado interfaces de la manera tradicional, colocando controles en un espacio bidimensional, tratando de llenar el espacio especificado para la interfaz de la mejor forma posible. Y cuando hacemos referencia a la mejor forma posible, en realidad queremos decir que, muchas veces, las aplicaciones tratan de ocupar por completo cualquier espacio disponible de la superficie de la interfaz, colocando botones o cualquier otro tipo de controles all donde exista un espacio en blanco. Esto se debe al hecho de que, con el avance de la tecnologa y de la informacin en general, cada vez ms las aplicaciones de software necesitan mostrar mayor cantidad de datos en pantalla, ya que el usuario requiere ver ms informacin al mismo tiempo sin tener que navegar entre diferentes ventanas o pulsar varios botones para conseguir lo que le interesa. Por otro lado, tener que moverse de un lado al otro, y abrir y cerrar ventanas, muchas veces trae como consecuencia que datos importantes queden ocultos por las nuevas ventanas, y se llegue al punto en el que el usuario olvide por completo el porqu de la bsqueda inicial. Este tipo de desarrollo se propag, en especial, por la falta de soporte de los sistemas operativos y por la complejidad de desarrollo de los variados lenguajes de programacin usados para crear las diferentes aplicaciones. En muchos casos, las interfaces de las aplicaciones, por estas restricciones, llegan a presentarse como la que podemos ver en la siguiente figura.

Figura 1. Una interfaz sobrecargada es poco prctica para el usuario.

Existen diferentes formas de mejorar la experiencia del usuario en nuestras aplicaciones, as como tambin es posible optimizar el espacio de nuestra aplicacin
156

Mover objetos

para mostrar, de forma ms natural para el usuario, la informacin requerida. Si bien no es el objetivo de este libro hablar de estas tcnicas, resulta importante mantener este pensamiento en el momento de realizar el diseo de aplicaciones. De cualquier manera, una de estas tcnicas, cada vez ms usada, es la de desplazar o mover objetos dentro del rea de la interfaz de la aplicacin. De esta forma, los elementos principales se mantienen todo el tiempo visibles, de manera constante, y dan paso a otros elementos creados a partir de la seleccin o interaccin del usuario con los elementos ms importantes. Por esto, el movimiento de objetos no resulta ajeno a Silverlight, que permite modificar los estados, formas, tamaos y posicin de los diferentes controles mientras ejecutamos nuestra aplicacin. Durante este captulo, hablaremos de las caractersticas provistas por Silverlight para poder mejorar las interfaces de las aplicaciones por medio del uso de movimiento y modificacin del comportamiento visual de los controles y de los componentes.

Figura 2. Una vista de Microsoft Surface, que permite arrastrar y mover elementos al tocarlos con la mano.

RRR

INTERFAZ DE USUARIO

Una interfaz de usuario demasiado cargada ocasionar rechazo por parte de ste. Es necesario, siempre que podamos, dejar las interfaces lo ms simples y claras posibles, incluso moviendo los elementos en la pantalla durante la ejecucin y abriendo la menor cantidad posible de ventanas o elementos que obstruyan la visin de datos importantes.

157

5. LUZ, CMARA, ACCIN

Transformaciones
Las transformaciones son uno de los modificadores de objetos disponibles en Silverlight. Con ellas, es posible cambiar la apariencia y el comportamiento de los controles y componentes de la interfaz. Es posible rotarlos, escalarlos, distorsionarlos, modificar su posicin relativa a un punto, as como invertir su posicin vertical u horizontal. Podemos ver, a continuacin, la lista de transformaciones disponibles: Transformacin de traslacin: esta transformacin modifica la posicin del objeto dentro del eje de coordenadas X e Y. Es til para desplazar o ajustar el objeto en una coordenada especfica en forma independiente de la posicin dentro del contenedor. Transformacin de rotacin: la transformacin de rotacin sirve para girar el objeto sobre la base de una cantidad de grados definida. Esta transformacin otorga la libertad suficiente para amoldar controles tpicamente horizontales y verticales, como botones y grillas de datos, entre otros, en posiciones no tradicionales. Transformacin escalar: una transformacin escalar hace referencia a la posibilidad de modificar el tamao o la escala del objeto Silverlight. Si aplicamos esta transformacin, podremos agrandar o achicar el tamao del objeto, incluido su contenido. Debido a que los controles y los componentes en XAML se forman segn la conjuncin de otros elementos, al aplicar esta transformacin, Silverlight aplicar la misma a todos los elementos internos del objeto modificado, por lo que no tendremos que preocuparnos por las proporciones de esos elementos internos, ya que estos se ajustarn en forma proporcional a su contenedor. Transformacin de distorsin: la transformacin de distorsin o la accin de sesgado permite torcer los objetos para el eje X e Y. Este mecanismo resulta ideal en aquellos casos en los cuales necesitemos simular elementos de tres dimensiones en un ambiente bidimensional o si queremos generar algn tipo de perspectiva en los objetos. Debido a que es posible aplicar ms de una transformacin al mismo tiempo sobre un objeto, stas pueden ser agrupadas dentro de un tag XAML comn. El tag <TransformGroup> representa esta agrupacin y deberemos usarlo como agrupador de los otros tags representativos para cada transformacin.

RRR

TRANSFORMACIONES

Al aplicar una transformacin a cualquier objeto, ste se redibujar en forma instantnea. Esto es por dems til para generar animaciones en tiempo de ejecucin en nuestra aplicacin, ya que no necesitaremos de clculos o de imgenes pregeneradas para conseguir el efecto deseado.

158

Mover objetos

Figura 3. Un control DataGrid con diferentes transformaciones aplicadas.

Las transformaciones, as como otros efectos en Silverlight, son generados en tiempo de ejecucin y de manera dinmica. Esto resulta muy beneficioso en comparacin con otras tecnologas, ya que el tamao del archivo de Silverlight creado resulta mucho ms pequeo. Esto se debe a que no es necesario que se genere por cada efecto un nuevo elemento con el resultado del efecto. Si pensamos en una transformacin sobre una imagen de tamao considerable, por cada transformacin aplicada a sta, se podra generar una nueva imagen con el nuevo resultado. Si se agregara cada una de ellas al archivo final, se acrecentara su tamao en una proporcin equivalente al tamao de la imagen por la cantidad de imgenes creadas. Al calcular los efectos en tiempo de ejecucin, esto se evita, y as se mejora enormemente la optimizacin en la utilizacin de recursos.

Transformacin de traslacin
La transformacin de traslacin es usada para desplazar o colocar un objeto en una posicin en X y en Y dentro del lienzo de una aplicacin. En la Figura 4, el rectngulo se encuentra por encima de la lnea que divide las dos columnas de la grilla.

RRR

TRASLACIN EN AGRUPADORES

Los controles de agrupacin, como vimos en captulos anteriores, pueden contener otros controles y manejarlos como un conjunto agrupado. Si necesitamos mover ms de un control al mismo tiempo, es posible aplicar una transformacin de traslacin al contenedor de estos controles en lugar de hacerlo uno por uno.

159

5. LUZ, CMARA, ACCIN

Figura 4. El rectngulo se muestra desplazado en X y en Y.

En el cdigo de la Figura 4, podemos notar algunas cuestiones interesantes obtenidas al haber aplicado la transformacin.
<Grid x:Name=LayoutRoot Background=White ShowGridLines=True> <Grid.RowDefinitions> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Rectangle Height=30 Grid.Column=0 Grid.Row=0 VerticalAlignment=Top Fill=#FFAF2727 Stroke=#FF000000 RenderTransformOrigin=0.5,0.5> <Rectangle.RenderTransform> <TransformGroup> <TranslateTransform X=150 Y=150/> </TransformGroup> </Rectangle.RenderTransform> </Rectangle> </Grid>

Si bien hemos definido dos columnas y una fila en la grilla, y el rectngulo est posicionado en la primera columna y la primera fila de acuerdo con los atributos
160

Mover objetos

Grid.Column

y Grid.Row, debido a la transformacin aplicada, ste se encuentra desplazado 150 pixeles en el eje X y 150 pixeles en el eje Y.

Transformacin de rotacin
Con esta transformacin, podremos rotar cualquier objeto. Aplicando la misma transformacin al rectngulo anterior, obtenemos el resultado que observamos en la Figura 5. Para conseguir esta transformacin debemos aplicar el siguiente cdigo.
<Grid x:Name=LayoutRoot Background=White> <Rectangle Margin=87,144,155,127 Fill=#FF4366DE Stroke=#FF000000 RenderTransformOrigin=0.5,0.5> <Rectangle.RenderTransform> <TransformGroup> <RotateTransform Angle=45/> </TransformGroup> </Rectangle.RenderTransform> </Rectangle> </Grid>

Figura 5. Un rectngulo rotado 45 grados a favor del reloj.

posee dos atributos adicionales que resultan tiles para especificar el punto de rotacin. En el ejemplo anterior, el punto de rotacin haba sido especificado mediante el atributo RenderTransformOrigin, separando con una coma el punto de rotacin en X y en Y. En este ejemplo, el punto de rotacin se encuentra posicionado en el centro del objeto especificando 0.5 (50%) para X y
<RotateTransform>
161

5. LUZ, CMARA, ACCIN

(50%) para Y. Como resultado, teniendo una copia del mismo rectngulo, pero con una rotacin de 90 grados, ste gira sobre el punto central del elemento. Si bien podemos utilizar RenderTransformOrigin, tambin es vlido utilizar los atributos CenterX y CenterY dentro del tag <RotateTransform> para realizar el mismo trabajo que el del atributo anterior. En la Figura 6, vemos los dos casos. En ellos, a un grupo de elementos, no se le especifica un punto de rotacin, lo que causa que este punto sea el extremo superior izquierdo.
0.5

Figura 6. Dos grupos de rectngulos con su centro de rotacin modificado.

Podemos ver en el siguiente cdigo las diferencias aplicadas en cada caso.


<Rectangle Margin=18,146,0,125 Fill=#FF4366DE Stroke=#FF000000 RenderTransformOrigin=0.5,0.5 HorizontalAlignment=Left Width=158> <Rectangle.RenderTransform> <TransformGroup> <RotateTransform Angle=45/> </TransformGroup> </Rectangle.RenderTransform> </Rectangle> <Rectangle Margin=18,146,0,125 Fill=#FF4366DE Stroke=#FF000000 HorizontalAlignment=Left Width=158> <Rectangle.RenderTransform> <TransformGroup> <RotateTransform Angle=90 CenterX=79 CenterY=15/> </TransformGroup>

162

Mover objetos

</Rectangle.RenderTransform> </Rectangle> <Rectangle Margin=0,86,26,0 Fill=#FF4366DE Stroke=#FF000000 Width=158 HorizontalAlignment=Right VerticalAlignment=Top Height=29> <Rectangle.RenderTransform> <TransformGroup> <RotateTransform/> </TransformGroup> </Rectangle.RenderTransform> </Rectangle> <Rectangle Margin=0,86,26,0 Fill=#FF4366DE Stroke=#FF000000 Width=158 HorizontalAlignment=Right Height=29 VerticalAlignment=Top> <Rectangle.RenderTransform> <TransformGroup> <RotateTransform Angle=30/> </TransformGroup> </Rectangle.RenderTransform> </Rectangle> ...

Un punto que debemos tener en cuenta sobre cul de los dos atributos necesitamos usar radica en la forma de calcular la posicin del punto de rotacin. Por su parte, RenderTransformOrigin utiliza un valor porcentual, siendo 1 equivalente a 100%. Si el valor de RenderTransformOrigin es equivalente a 1,1, ste ser igual a la esquina inferior derecha, mientras que 0,0 representar la esquina superior izquierda. Este mtodo para especificar el punto de rotacin puede resultar, en algunos casos, ms fcil de calcular, en especial para deducir el centro de rotacin, ya que ste es representado por el valor 0.5,0.5. Sin embargo, podra ser complejo de calcular para puntos intermedios. Por otro lado, para el caso de CenterX y CenterY, se utilizan valores numricos equivalentes al tamao del objeto por rotar. As, si el objeto ocupa 100 pixeles de ancho y 50 pixeles de alto, el valor para CenterX deber ser de 50, mientras el valor para CenterY deber ser de 25. Como ya dijimos, los controles y componentes tambin pueden ser afectados por estas transformaciones. Ellos seguirn prestando la misma funcionalidad, pero, en lo visual, se desplegarn basados en su transformacin. En la Figura 7, vemos cmo una serie de controles aplican la transformacin de rotacin sin perder funcionalidad.
163

5. LUZ, CMARA, ACCIN

Figura 7. Controles para entrada de datos con transformacin de rotacin.

En el siguiente cdigo, vemos ambos controles.


<Button HorizontalAlignment=Left Margin=0,45,0,0 VerticalAlignment=Top Content=Aceptar d:LayoutOverrides=Width RenderTransformOrigin=0.5,0.5> <Button.RenderTransform> <TransformGroup> <RotateTransform Angle=-90/> </TransformGroup> </Button.RenderTransform> </Button> <TextBox HorizontalAlignment=Left Margin=-55,0,0,123 VerticalAlignment=Bottom Width=158 RenderTransformOrigin=0.5,0.5 Text= TextWrapping=Wrap d:LayoutOverrides=Height> <TextBox.RenderTransform> <TransformGroup> <RotateTransform Angle=-90/> </TransformGroup> </TextBox.RenderTransform> </TextBox>

Si bien los valores para el punto de rotacin que hemos usado hasta el momento se aplican a la parte interna del objeto rotado, es posible utilizar valores que sobrepa164

Mover objetos

sen los lmites del objeto por rotar. De esta manera, conseguiremos que el eje de rotacin quede fuera del objeto. Esto har que el punto de rotacin marque la posibilidad de rotacin por sobre una circunferencia y permitir que el elemento gire alrededor de este punto como si se tratase de una rbita en un punto especfico.

Transformacin escalar
La transformacin escalar es til para modificar el tamao de los objetos, tanto en largo como en alto o en una escala para X como para Y, si trasladamos las dimensiones a un eje XY. En la figura que vemos a continuacin, podemos apreciar dos rectngulos con sus respectivas modificaciones.

Figura 8. Dos rectngulos modificados por la transformacin escalar.

Los atributos utilizados para modificar la escala de los objetos son ScaleX y ScaleY, ambos usados dentro del tag <ScaleTransform>, que hace referencia a este tipo de transformacin. Podemos ver el cdigo utilizado para generar la Figura 8 a continuacin.
<Rectangle Margin=125,57,149,0 Fill=#FF82D442 Stroke=#FF000000 RenderTransformOrigin=-0.008,0.967 Height=30 VerticalAlignment=Top> <Rectangle.RenderTransform> <TransformGroup> <ScaleTransform ScaleX=1.3 ScaleY=1.3/> </TransformGroup> </Rectangle.RenderTransform> </Rectangle>

165

5. LUZ, CMARA, ACCIN

<Rectangle Margin=125,57,149,0 Fill=#FF9FCE7A Stroke=#FF000000 Height=30 VerticalAlignment=Top/> <Rectangle Margin=125,0,149,106 Fill=#FF406225 Stroke=#FF000000 Height=30 VerticalAlignment=Bottom RenderTransformOrigin=0.5,0.5> <Rectangle.RenderTransform> <TransformGroup> <ScaleTransform ScaleX=1.3 ScaleY=1.3/> </TransformGroup> </Rectangle.RenderTransform> </Rectangle> <Rectangle Margin=125,0,149,106 Fill=#FF293B1A Stroke=#FF000000 Height=30 VerticalAlignment=Bottom/>

y ScaleY utilizan un valor numrico que representa el porcentaje de crecimiento que recibir el objeto. En el ejemplo, utilizamos el valor 1.3, que representa el 100% del tamao original ms un 30% adicional, por lo que el objeto habr crecido 30%, tanto en X como en Y. Al igual que la transformacin de rotacin, la transformacin escalar tambin hace uso de los atributos CenterX y CenterY, as como de RenderTransformOrigin, aplicando las mismas reglas antes mencionadas. En la Figura 9, podemos ver dnde est posicionado el eje de crecimiento para el rectngulo superior, el cual es cercano a la esquina inferior izquierda del objeto. El rectngulo inferior utiliza su centro como punto de crecimiento. Debido a esto, vemos que este rectngulo crece hasta cubrir el rectngulo original, y lo hace desde su centro hacia las cuatro direcciones del eje XY.
ScaleX

Figura 9. El rectngulo superior modifica su eje de crecimiento.


166

Mover objetos

Transformacin de distorsin
torsin.

Esta ltima transformacin modifica la apariencia del objeto aplicando ngulos de Pensemos en un objeto de forma cuadrada o rectangular. Cada esquina de este objeto es representada por un ngulo de 90 grados. Esta transformacin tiene el objetivo de modificar estos ngulos rectos sobre la base de un valor numrico expresado, tambin, en grados. En la siguiente figura, vemos cmo es distorsionada la apariencia de un objeto cuadrado.

Figura 10. El objeto es distorsionado para generar una vista en perspectiva.

En el cdigo que aparece a continuacin, podemos ver que los atributos AngleX y AngleY son configurados con los valores de -10 grados cada uno. Estos dos atributos, junto con RenderTransformOrigin, son los que le otorgan el aspecto final al objeto una vez distorsionado. Si modificamos el valor RenderTransformOrigin para que se encuentre fuera del centro del objeto, conseguiremos distorsiones no simtricas, que pueden ser tiles, basadas en la perspectiva que queramos lograr.
<Rectangle Margin=134,102,186,118 Fill=#FF43A6C3 Stroke=#FF000000 RenderTransformOrigin=0.5,0.5> <Rectangle.RenderTransform> <TransformGroup> <SkewTransform AngleX=-10 AngleY=-10/> </TransformGroup> </Rectangle.RenderTransform> </Rectangle>

167

5. LUZ, CMARA, ACCIN

Aplicar todas las transformaciones


Como mencionamos, es posible aplicar ms de una transformacin a nuestros objetos, incluso, se pueden aplicar estas transformaciones a los controles para entrada de datos, as como para aquellos que despliegan la informacin. Para poner en prctica esto, extenderemos un poco el ejemplo creado en el captulo 3, modificando la apariencia del control DataGrid, adems de agregar algunos otros elementos llamativos a la interfaz creada para ese ejemplo.

Figura 11. Resultado final despus de haber aplicado transformaciones a los controles Silverlight.

El primer paso, consiste en aplicar transformaciones a nuestro DataGrid, que estar ubicado en una de las dos columnas de la grilla contenedora. Adems, el control DataGrid fue colocado dentro de un control Border para simular las puntas redondeadas, aplicndole un color degradado. Estos controles, finalmente, se encuentran dentro de un control StackPanel. Sobre este StackPanel, aplicaremos las transformaciones.
<Grid x:Name=LayoutRoot> <Grid.RowDefinitions> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width=0.512*/> <ColumnDefinition Width=0.488*/> </Grid.ColumnDefinitions> <Grid.Background>

168

Mover objetos

<LinearGradientBrush EndPoint=0.5,1 StartPoint=0.5,0> <GradientStop Color=#FF2A77FF/> <GradientStop Color=#FFFFFFFF Offset=1/> </LinearGradientBrush> </Grid.Background> <StackPanel HorizontalAlignment=Stretch VerticalAlignment=Stretch Margin=0,0,8,0 RenderTransformOrigin=0.5,0> <StackPanel.RenderTransform> <TransformGroup> <ScaleTransform ScaleY=1/> <SkewTransform AngleY=-28/> <RotateTransform/> <TranslateTransform Y=25/> </TransformGroup> </StackPanel.RenderTransform> <TextBlock FontFamily=Arial FontSize=20 FontStyle=Normal FontWeight=Bold Text=Registros disponibles TextWrapping=Wrap/> <Border BorderThickness=1,1,1,1 CornerRadius=10,10,10,10 BorderBrush=#FF000000 Height=450> <Border.Background> <LinearGradientBrush EndPoint=0.5,1 StartPoint=0.5,0> <GradientStop Color=#FF9BD3E8/> <GradientStop Color=#FF2D88A9 Offset=1/> </LinearGradientBrush> </Border.Background> <data:DataGrid BorderThickness=0,0,0,0 HorizontalContentAlignment=Center VerticalContentAlignment=Center x:Name=MiGrilla Height=400 HorizontalAlignment=Center VerticalAlignment=Center Width=300/> </Border> </StackPanel>

Para mostrar la cantidad de registros seleccionados en cada bsqueda, usamos un control TextBlock con una transformacin de rotacin.
<TextBlock HorizontalAlignment=Right VerticalAlignment=Bottom Text=Registros TextWrapping=Wrap Grid.Column=1

169

5. LUZ, CMARA, ACCIN

d:LayoutOverrides=HorizontalAlignment, Height Margin=0,0,172.962,76.866 RenderTransformOrigin=0,1 Opacity=0.5 FontSize=48 FontFamily=Lucida Sans Unicode FontWeight=Bold FontStyle=Normal x:Name=registros Width=318.554> <TextBlock.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform Angle=-90/> <TranslateTransform Y=76.23 X=150.674/> </TransformGroup> </TextBlock.RenderTransform> </TextBlock>

Luego, modificamos el cdigo encargado de realizar las bsquedas sobre la base del texto introducido por el usuario para desplegar la cantidad de registros encontrados.
private void Button_Click(object sender, RoutedEventArgs e) { var q = from c in productos where c.Nombre.Contains(this.buscador.Text) || c.Descripcion.Contains(this.buscador.Text) select c; this.MiGrilla.ItemsSource = q; this.registros.Text = Registros + q.Count<Producto>().ToString(); }

De esta manera, probamos que las transformaciones pueden ser no slo aplicadas a formas bsicas, sino a cualquier elemento creado por cdigo XAML.

Animaciones
Como hemos notado con las transformaciones, stas no generan nuevos elementos del objeto modificado, sino que actan sobre l en tiempo de ejecucin de la aplicacin Silverlight. Esto ahorra, por un lado, los recursos transmitidos hacia el cliente que visualiza nuestra aplicacin, y por otro, nos da la posibilidad de modificar estas transformaciones en tiempo de ejecucin, no atndonos a un guin establecido con anterioridad. Basadas en este modelo, las animaciones en
170

Mover objetos

Silverlight se diferencian bastante de los modelos tradicionales de animacin, que, por lo general, se representan mediante la creacin de cuadros reproducidos en forma sucesiva. Este modelo, el del cuadro a cuadro, tambin resulta costoso en recursos de cara al usuario, ya que por cada cuadro es necesario transmitir cada uno de stos como si se tratara de la reproduccin de una pelcula o de un dibujo animado. Pero adems, renace el problema de elementos guionados, que nos llevan a pensar en todas las posibles alternativas que los elementos de nuestra aplicacin podran tener. Por el contrario, Silverlight utiliza para las animaciones el mismo modelo que hemos visto en las transformaciones. Esto significa que podremos animar los distintos elementos de nuestra aplicacin en tiempo de ejecucin, pudiendo alterar o generar nuevo contenido basado en las necesidades del usuario. A pesar de esto, es posible que la cantidad de animaciones que podamos generar con Silverlight parezcan limitadas, ya que el modelo reduce esta cantidad a tres tipos de animaciones, los cuales tendrn la capacidad de modificar las propiedades y los atributos de los objetos por animar. DoubleAnimation: este modelo de animacin est orientado a modificar los valores numricos de las propiedades y atributos del objeto. ColorAnimation: este tipo de animacin es utilizado para modificar valores que no pueden ser representados por nmeros reales. Los colores, por ejemplo, suelen representarse en hexadecimal. PointAnimation: esta animacin tiene la capacidad de modificar valores en propiedades que trabajen con puntos. Este modelo de animacin est fuertemente relacionado con movimientos de objetos y con el desplazamiento en el eje de coordenadas XY.

DoubleAnimation
Como dijimos, este modelo de animacin es til cuando queremos modificar los valores numricos de las propiedades y atributos de cualquier objeto. Para declarar una animacin de este tipo, podemos usar el siguiente cdigo:
<DoubleAnimation From=128 To=200 Duration=0:0:10/>

Los atributos From (desde) y To (hasta) determinarn los rangos entre los cuales el atributo por modificar se ir alternando. En el caso anterior, el valor en cuestin ir desde 128 a 200; estos valores se distribuirn de acuerdo con el tiempo especificado por el atributo Duration (duracin). Este ltimo atributo es representado por los valores correspondientes a horas, minutos y segundos (hh:mm:ss). Para el ejemplo, la animacin tendr una duracin de 10 segundos. En la Figura 12, vemos cmo, al aplicar esta animacin sobre la propiedad Width de un rectngulo, ste modifica su tamao segn dicha animacin.
171

5. LUZ, CMARA, ACCIN

Figura 12. El rectngulo en el navegador de la izquierda, antes de que ocurriese la animacin; y el de la derecha, una vez ocurrida.

Para lograr esto, lo primero que deberemos hacer es crear nuestro rectngulo.
<Grid x:Name=LayoutRoot Background=White> <Rectangle MouseEnter=Rectangulo_MouseEnter x:Name=Rectangulo Height=55 HorizontalAlignment=Left Margin=69,57,0,0 VerticalAlignment=Top Width=128 Fill=#FF407280 Stroke=#FF000000> </Rectangle> </Grid>

Una vez que tenemos el rectngulo en posicin, deberemos crear la animacin.


<UserControl.Resources> <Storyboard x:Name=Animacion1> <DoubleAnimation From=128 To=200 Duration=0:0:01 Storyboard.TargetProperty=Width Storyboard.TargetName=Rectangulo></DoubleAnimation> </Storyboard> </UserControl.Resources>

Esta animacin es considerada un recurso genrico de todo el control XAML, por este motivo, deberemos colocarla dentro del tag <UserControl.Resources>.
172

Mover objetos

El siguiente tag es el <Storyboard>. Este tag agrupar en un conjunto todas las animaciones que se van a aplicar a un mismo objeto o, si lo preferimos, animaciones para diferentes objetos que podremos ejecutar al mismo tiempo como un conjunto. Es importante la presencia de un nombre para el tag <Storyboard> por medio del atributo x:Name, ya que de esta forma podremos iniciar la ejecucin del conjunto de animaciones invocando su nombre. Los atributos del tag <DoubleAnimation>, Storyboard. TargetProperty y Storyboard.TargetName hacen referencia a la propiedad que esa animacin modificar y al nombre del objeto que contiene la propiedad, respectivamente. Para este caso, Storyboard.TargetProperty hace referencia a la propiedad Width del objeto definido por Storyboard.TargetName, que en este caso es Rectangulo. Para activar la animacin, es necesario especificar el momento en el cual sta se iniciar. Esto lo logramos desde nuestro cdigo C#, de la siguiente manera, donde animacin es el nombre previamente configurado en el tag <Storyboard>:
this.Animacion1.Begin();

ColorAnimation
es necesaria para animaciones que modifiquen el color de los objetos. Posee iguales atributos que los presentados en la animacin del tipo DoubleAnimation y, para usarla, deberemos declararla como sigue:
ColorAnimation
<ColorAnimation></ColorAnimation>

Figura 13. A la derecha, el rectngulo presenta un cambio de color, el mismo que fue aplicado en forma paulatina con la animacin.
173

5. LUZ, CMARA, ACCIN

La declaracin completa de esta animacin podemos verla a en el siguiente cdigo, que pasa del color original del rectngulo hasta el color negro definido por el atributo To. En este caso, modificamos la propiedad Fill, y su atributo Color.Storyboard. TargetProperty hace referencia a este conjunto de propiedades y atributos.
<ColorAnimation From=#FF407280 To=#FF000000 Duration=0:0:01 Storyboard.TargetProperty=(Fill).(Color) Storyboard.TargetName=Rectangulo></ColorAnimation>

PointAnimation
PointAnimation es el ltimo de los modelos de animacin propuestos por Silverlight. Puede ser usado para modificar puntos de coordenadas XY. Para declarar esta animacin, debemos hacerlo de la siguiente manera:
<PointAnimation></PointAnimation>

Para graficar este modelo de animacin, crearemos un crculo que desplazaremos sobre la base de su centro de dibujo. Podemos declarar este elemento como sigue:
<Path Fill=#FF407280 MouseEnter=Path_MouseEnter> <Path.Data> <EllipseGeometry x:Name=GeometriaCircular Center=200,200 RadiusX=40 RadiusY=40 /> </Path.Data> </Path>

Figura 14. Este crculo se desplazar sobre la base de su centro de dibujo.


174

Mover objetos

La animacin por puntos la declararemos dentro de su propio tag <Storyboard>, el cual modificar el atributo Center del crculo creado.
<Storyboard x:Name=Animacion2> <PointAnimation From=0,200 To=300,200 Duration=0:0:2 Storyboard.TargetName=GeometriaCircular Storyboard.TargetProperty=Center> </PointAnimation> </Storyboard>

Debido a que se trata de un punto en el mapa de coordenadas, tanto el atributo From como To presentan el patrn XY separados por una coma. Al aplicar esta animacin, veremos que el crculo se desplazar de izquierda a derecha cubriendo 300 pixeles de distancia en 2 segundos. Como ya hemos podido notar, los atributos de configuracin para las animaciones son los mismos entre los modelos, y existen otros elementos comunes para estas animaciones que pueden ser de utilidad. RepeatBehavior: este atributo dictamina la cantidad de veces que la animacin se repetir una vez que llegue a su fin. Podemos configurar para que se repita una cantidad de veces determinada usando un valor numrico, o la palabra Forever (para siempre), para que la animacin sea continua. AutoReverse: es posible optar entre True (verdadero) o False (falso). Si configuramos esta propiedad en True, la animacin retroceder sobre sus pasos una vez finalizada. SpeedRatio: este atributo representa la velocidad en la animacin. Por defecto, el valor utilizado es 1, lo que quiere decir que la animacin trabajar a velocidad normal. Si incrementamos este valor a 2, la animacin ser dos veces ms rpida que la velocidad normal. Este valor no es relacin de cuadros por segundo, sino la rapidez o lentitud con las que avanzar y concluir la animacin. As, si tenemos una animacin con una duracin de 5 segundos y configuramos el valor de este atributo a 2, la animacin debera concluir en 2 segundos y medio, pero, si el valor es equivalente a 0.5, la animacin tardara el doble. BeginTime: representa un lapso de tiempo que la animacin esperar antes de iniciarse. Este lapso es representado de igual forma que el del atributo Duration, mediante la nomenclatura hh:mm:ss.

Animaciones y transformaciones
Con un poco de imaginacin, veremos que la combinacin de animaciones con los atributos de los controles nos puede dar suficiente libertad como para hacer casi todo lo que necesitemos. Podramos por ejemplo, conjugar animaciones con las transformaciones vistas al principio de este captulo para conseguir no slo modificar tamaos, colores o posiciones de los objetos, sino tambin poder cambiar de aspecto, rotarlo,
175

5. LUZ, CMARA, ACCIN

distorsionarlo o agrandarlo a gusto. Para graficar esto, utilizaremos un objeto al cual le aplicaremos una animacin para una transformacin de rotacin.

Figura 15. Animando una transformacin de rotacin.

El primer paso consiste en declarar el objeto con los valores de la transformacin. Es importante tener estos valores por defecto ya que, de no existir, no podran ser encontrados por el elemento que genera la animacin.
<Rectangle Height=29 VerticalAlignment=Top Margin=149,83,116,0 Fill=#FFBF3434 MouseEnter=Rectangle_MouseEnter> <Rectangle.RenderTransform> <RotateTransform Angle= x:Name=anguloRectangulo></RotateTransform> </Rectangle.RenderTransform> </Rectangle>

Tambin podemos ver que el elemento <RotateTransform> tiene un atributo x:Name, lo que har que sea mucho ms simple poder acceder a l desde la animacin y no tener que crear cadenas de texto largas para indicar cul es el atributo sobre el que actuar la animacin. Por ltimo, creamos la animacin para esta transformacin:
<Storyboard x:Name=Animacion> <DoubleAnimation From=0 To=90

176

Mover objetos

Storyboard.TargetName=anguloRectangulo Storyboard.TargetProperty=Angle></DoubleAnimation> </Storyboard>

La animacin se aplicar sobre el atributo Angle (ngulo), aplicndole grados que pueden ir desde 0 a 90. Para dar inicio a esta animacin, deberemos escribir el cdigo que vemos a continuacin:
private void Rectangle_MouseEnter(object sender, MouseEventArgs e) { this.Animacion.Begin(); }

Figura 16. Podremos aplicar este tipo de transformaciones a cualquier elemento. En este caso, animamos un control DatePicker mediante una transformacin de rotacin.

_`

ANIMAR CURVAS

Debido a que podemos definir lneas sinusoidales, las cuales cuentan con puntos XY de inicio y puntos XY de finalizacin adems de un radio de curva, es posible usar PointAnimation para animar esta curva en tiempo de ejecucin para lograr efectos de ondas.

177

5. LUZ, CMARA, ACCIN

Estilos y plantillas
En la mayora de los casos, usamos los controles provistos por Silverlight tal como son, sin modificar su apariencia visual predefinida. Esto puede ser til en muchos casos, pero existirn muchas ocasiones en las que deberemos adaptar estos elementos a nuestros diseos, y modificar las propiedades visuales de los componentes. Para lograr esto, solemos cambiar la apariencia visual control por control, algo que consumir tiempo y ser costoso, adems de generar cdigo XAML innecesario, agrandando el tamao de nuestra aplicacin y hacindola mucho ms complicada de modificar y mantener. Imaginemos que nuestra aplicacin cuenta con veinte botones y que, despus de haber modificado y terminado nuestro trabajo, nos encontramos con un nuevo requerimiento que implica tener que volver a cambiar el aspecto de estos botones. Hacer este cambio nos resultar un esfuerzo extremadamente costoso. Para solucionar el problema, debemos hacer uso de estilos. Estos estilos trabajan de manera similar a las hojas de estilo (CSS, Cascade Style Sheets) de HTML, donde podremos definir un comportamiento visual general para los controles y aplicarlos a todos los controles que necesitemos. As, al modificar un estilo, es posible afectar a todos los controles que consuman de ste. Las plantillas o moldes, por otra parte, son utilizados para redefinir el comportamiento, como la apariencia visual sobre la base de un control inicial, pero la redefinicin de la apariencia visual va mucho ms all que la conseguida con estilos. Mientras que con estilos podemos modificar las caractersticas tales como color, ancho, alto, o tipo de fuente usada en el control, con las plantillas podremos hacer que, por ejemplo, un botn no tenga la apariencia de un botn como tal, sino que, por el contrario, se transforme en un crculo, en una imagen o en cualquier otro elemento que est acorde a nuestras necesidades visuales.

Estilos
Luego de lo dicho anteriormente, veremos cmo modificar la apariencia visual de los controles con la creacin y aplicacin de estilos a los controles ya existentes. Para poder declarar un estilo, debemos seguir el siguiente patrn:
<UserControl.Resources> <Style x:Key=Estilo1 TargetType=TextBox> ... </Style> </UserControl.Resources>

Podemos ver que el estilo es declarado dentro de los recursos del tag <UserControl> de la misma forma que hicimos con las animaciones y el tag <Storyboard>. Si bien sta es una opcin, tambin podramos declarar este estilo en los recursos globales de toda la aplicacin, colocndolo dentro del archivo App.xaml.
178

Mover objetos

<Application.Resources> <Style x:Key=Estilo1 TargetType=TextBox> ... </Style> </Application.Resources>

De esta forma, si tenemos ms de una pgina XAML en nuestra aplicacin, podremos compartir el estilo entre ellas. Por otro lado, tambin vemos que aparecen dos nuevos atributos en la declaracin de un estilo. x:Key: este atributo es necesario para poder identificar el estilo creado. Consumiremos el estilo mediante este nombre. TargetType: tipo de control que podr usar este estilo. Con este atributo, restringimos el uso del estilo a un tipo de control. Es similar a la capacidad de ASP.net de generar estilos visuales para los controles, pudiendo crear estilos para tipos especficos.

Figura 17. Varios TextBox que consumen del mismo estilo.

CDIGO DE EJEMPLO
En la Web, podemos encontrar cientos de sitios con cdigo de ejemplo para Silverlight 2. De cualquier manera, uno de los destacados es el sitio oficial de Silverlight, hasta el que podemos navegar para descargar excelentes ejemplos. La direccin es http://silverlight.net.

179

5. LUZ, CMARA, ACCIN

Los estilos se aplican a cada una de las propiedades del objeto que queremos configurar. En el caso de la Figura 17, el estilo utilizado es el siguiente:
<Style x:Key=Estilo1 TargetType=TextBox> <Setter Property=Background> <Setter.Value> <LinearGradientBrush EndPoint=0.5,1 StartPoint=0.5,0> <GradientStop Color=#FF88CAF0/> <GradientStop Color=#FFFFFFFF Offset=1/> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property=BorderBrush> <Setter.Value> <LinearGradientBrush EndPoint=0.5,1 StartPoint=0.5,0> <GradientStop Color=#FFA3AEB9/> <GradientStop Color=#FF9DBACE Offset=0.567/> <GradientStop Color=#FF000000 Offset=1/> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property=Foreground Value=#FF342449/> <Setter Property=BorderThickness Value=2,2,2,2/> <Setter Property=MinHeight Value=25/> <Setter Property=Text Value=/> </Style>

Necesitamos colocar, por cada atributo por modificar, un tag <Setter>, el mismo que especifica el nombre de la propiedad (Property) que se modificar y su valor (Value). Es posible tambin especificar valores para tipos complejos mediante el uso de <Setter. Value>, colocando dentro de ste la descripcin del tipo complejo. Por ltimo, deberemos aplicar el estilo al control que lo consumir de la siguiente manera:
<TextBox Height=25 Width=120 Style={StaticResource Estilo1}/>

Si colocamos los estilos dentro de la declaracin del tag <UserControl> como dentro del tag <Application>, es posible reutilizarlos de forma global, aunque tambin
180

Mover objetos

pueden reducir el alcance de los estilos limitndolos al control en s o a un conjunto de controles contenidos por algn control contenedor. En la Figura 18, el botn de la derecha est contenido por un control StackPanel, que tiene declarado el estilo para el botn, estilo que slo podr ser consumido por los controles contenidos por el StackPanel. La declaracin del estilo en el StackPanel es similar a la utilizada de manera global por el tag <UserControl> como el tag <Application> dentro del archivo App.xaml.
<StackPanel Margin=171,12,24,71> <StackPanel.Resources> <Style x:Key=EstiloContenido TargetType=Button> <Setter Property=BorderThickness Value=2,2,2,2/> <Setter Property=Background> ...

Figura 18. El botn de la derecha, contenido por un StackPanel consumiendo el estilo declarado.

RRR

EL ENFOQUE ASP.NET

Tratando de mantener concordancia entre desarrollos, los estilos poseen un comportamiento similar a las mscaras usadas en ASP.net. Esto garantiza que los desarrolladores web puedan fcilmente adaptarse a este modelo. Ms informacin en http://msdn.microsoft.com/es-es, buscando temas y mscaras.

181

5. LUZ, CMARA, ACCIN

Plantillas
Si el estilo nos permiti modificar los valores, atributos y propiedades visuales del control, las plantillas nos permitirn crear controles basndonos en otros y alterar el aspecto de stos. La ventaja significativa de las plantillas radica en que, utilizando como raz un control existente y pudiendo reusar sus eventos, podremos crear uno nuevo. Pensemos en la capacidad de un botn de disparar un evento cuando el usuario lo presiona con el mouse. Esta capacidad no est presente en todos los controles, por lo que podramos reutilizarla creando nuestro propio botn con un aspecto diferente del estndar. De esta forma, partiendo de un control inicial, construimos uno completamente nuevo.

Figura 19. Un nuevo botn construido sobre la base del control estndar. <Button HorizontalAlignment=Left Margin=120,91,0,0 VerticalAlignment=Top Content=Hacer Click> <Button.Template> <ControlTemplate TargetType=Button>

RRR

SIMILITUDES

Si hemos trabajado en el desarrollo web, especficamente en ASP.net, notaremos que el concepto detrs de las plantillas resulta similar al de la creacin de controles compuestos. Encontraremos ms informacin en http://msdn.microsoft.com/es-es, buscando control web compuesto.

182

Mover objetos

<Grid Height=38 Width=74> <Border Background=#FFB0ECE8 BorderBrush=#FF000000 BorderThickness=2,2,2,2 CornerRadius=5,0,5,0> <TextBlock Text={TemplateBinding Content} TextWrapping=Wrap Margin=3,3,3,3 HorizontalAlignment=Center VerticalAlignment=Center/> </Border> </Grid> </ControlTemplate> </Button.Template> </Button>

En el ejemplo, la plantilla se encuentra incrustada dentro del mismo control Button, por lo que esta configuracin slo aplicar a este botn y no a otros que pudiramos adicionar al proyecto. Tambin es posible ver la secuencia de controles usados para definir el nuevo elemento. Primero el uso del control Border usado para definir el contorno del botn y redondear dos de las esquinas del objeto. Dentro de ste, un control TextBlock utilizado para mostrar el texto del botn. Otro detalle es la aparicin del valor {TemplateBinding Content} dentro del atributo Text del control TextBlock. Este valor asegura que el control TextBlock muestre el contenido de la misma propiedad configurada en el control padre. Como el control Button posee un atributo llamado Content, lo que se escriba en ste ser transferido en forma automtica al atributo Text del control TextBlock. Podemos usar este tipo de enlazados con cualquier atributo o propiedad presente en los elementos hijo y que pudieran ser configurados desde el elemento padre. Como habremos notado, muchos controles en Silverlight poseen efectos que se disparan cuando el usuario interacta con ellos. Si el mouse pasa por encima del control, ste presenta una superficie de un color especial o, si es deshabilitado, el control se muestra con otro color. Esto se debe a que, en su interior, estos controles manejan animaciones basadas en distintos eventos por parte del usuario, por lo que, al redefinir un control, es posible tambin modificar estas animaciones. Veamos un ejemplo de las animaciones declaradas para el control Button personalizado.

RRR

RESTAURAR ESTADOS

Es importante agregar el tag <vsm:VisualState x:Name=Normal/> cuando trabajemos con animaciones en las plantillas. Si hacemos esto, lograremos que, cuando el elemento modificado no est aplicando ninguna animacin, el objeto vuelva, en forma automtica, a su estado original.

183

5. LUZ, CMARA, ACCIN

<Button x:Name=Boton1 VerticalAlignment=Top Content=Hacer Click Margin=114,40,127,0 Height=50> <Button.Template> <ControlTemplate TargetType=Button> <Grid Width={TemplateBinding Width} Height={TemplateBinding Height}> <vsm:VisualStateManager.VisualStateGroups> <vsm:VisualStateGroup x:Name=EstadosComunes> <vsm:VisualState x:Name=Normal/> <vsm:VisualState x:Name=MouseOver> <Storyboard> <DoubleAnimation From=11 To=16 Duration=0:0:0.2 Storyboard.TargetName=textInterno Storyboard.TargetProperty=FontSize> </DoubleAnimation> </Storyboard> </vsm:VisualState> </vsm:VisualStateGroup> </vsm:VisualStateManager.VisualStateGroups> <Border Background=#FFB0ECE8 BorderBrush=#FF000000 BorderThickness=2,2,2,2 CornerRadius=5,0,5,0 Width={TemplateBinding Width}> <TextBlock x:Name=textInterno Text={TemplateBinding Content} TextWrapping=NoWrap Margin=3,3,3,3 HorizontalAlignment=Center VerticalAlignment=Center FontSize=11/> </Border> </Grid> </ControlTemplate> </Button.Template> </Button>

En el cdigo anterior, introdujimos algunos tags nuevos: <vsm:VisualStateManager>: este tag representa el contenedor de los diferentes estados que puede contener el control. Dentro de ste, tenemos que agregar todos los estados por los cuales reaccionar el control.
184

Mover objetos

<vsm:VisualStateGroup>: este tag agrupa los estados en un contenedor comn bajo un nombre representativo. <vsm:VisualState>: representa un estado posible del control, adems de contener todas las animaciones que ese estado pueda representar.

Figura 20. Animaciones personalizadas en plantillas. A la izquierda, vemos el botn en su estado normal y, a la derecha, el mismo botn una vez aplicada la animacin.

De esta forma, las animaciones contenidas dentro del tag <vsm:VisualState x:Name= MouseOver> se ejecutarn cuando el usuario posicione el mouse sobre el botn. La animacin, en este caso, agrandar el tamao de la fuente del texto interno del botn. Con estas caractersticas no slo podemos modificar el control para que tenga el aspecto que nosotros queramos, sino que, adems, es posible manipular los estados por los cuales pasar nuestro control, pudiendo modificar su presentacin y comportamiento acorde a cmo el usuario interacte con l.

RESUMEN
En este captulo aprendimos a manipular los distintos elementos de Silverlight de forma que podamos quitarle rigidez a las aplicaciones que construyamos. Animaciones, transformaciones y estilos para los controles, as como algunas tcnicas para presentar mejor el contenido y hacer ms atractivas las interfaces con las que el usuario debe trabajar. En el prximo captulo, nos introduciremos otro poco en caractersticas visuales como las DeepZoom, y nos acercaremos ms an a los cdigos C# y JavaScript.

185

 ACTIVIDADES
PREGUNTAS TERICAS
1 Cuntos tipos de transformaciones podemos encontrar en Silverlight 2? 2 Si queremos especificar una transformacin, qu tag XAML debemos usar dentro del objeto que va a ser modificado? 3 Qu parmetros son necesarios para aplicar una transformacin de traslacin? 4 Cul es la unidad utilizada en una transformacin de rotacin? 5 Si necesitamos rotar un objeto mediante una transformacin de rotacin, siempre debemos realizarlo desde el centro del objeto? Es posible modificar este punto de rotacin? 6 Cundo debemos usar la animacin llamada ColorAnimation? 7 Cul es el formato utilizado para especificar el tiempo de duracin de las animaciones? 8 Qu debemos ejecutar desde cdigo C# para que una animacin se inicie? 9 Qu es un estilo en Silverlight 2? 10 Para qu usamos plantillas en Silverlight 2? 3 Busque animaciones xaml en http://msdn. microsoft.com/es-es para aprender ms sobre transformaciones y animaciones con Silverlight 2. 4 Ingrese en http://msdn.microsoft.com/ es-es y busque animaciones 3D avanzadas para conocer ms sobre simulaciones tridimensionales con Silverlight 2 mediante el uso de transformaciones y animaciones. 5 Ingrese en http://silverlight.net/learn/ y all busque 78708 para ver un video sobre animaciones con Silverlight 2. 2 Busque en Internet informacin sobre animaciones cuadro a cuadro con Silverlight 2.

EJERCICIOS PRCTICOS
1 Intente crear una animacin, utilizando ColorAnimation, para modificar el color de fondo de un control en el momento en el que el ratn se posicione sobre l.

186

Silverlight

Captulo

Cerrar el crculo
Este captulo est dedicado a tratar tres complementos de Silverlight. Y, si bien los llamaremos complementos, son tan importantes que merecen un captulo completo. Con stos podremos dibujar, transmitir videos y hasta manipular imgenes de alta definicin de forma simple.
MediaElement Ejecutar sonidos Video Elementos con video embebido Marcadores de video Deep Zoom Crear el primer Deep Zoom Incluir Deep Zoom en Silverlight Dibujar con InkPresenter Dibujar en forma manual Dibujar sobre otros elementos InkPresenter y reas de dibujo Resumen Actividades 188 188 194 195 196 199 200 203 208 212 215 217 219 220

SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com

6. CERRAR EL CRCULO

MEDIAELEMENT
En el captulo 2, realizamos un proyecto Silverlight que implementaba el control MediaElement para visualizar un video. Pero las caractersticas de este control pueden ir mucho ms lejos y, con esto, todo lo relacionado al manejo de video dentro de Silverlight. Este control no tiene como nico objetivo visualizar videos, ya que con l podremos tambin ejecutar sonidos o hacer lo que se conoce como streaming (reproduccin de videos bajo demanda). Veamos, entonces, cmo extender las capacidades de este control maximizando las potencialidades que presenta.

Ejecutar sonidos
Antes de utilizar el control MediaElement para ejecutar sonidos, debemos conocer los formatos soportados. Si bien el control tiene pleno soporte para los formatos creados por Microsoft, como el WMA (Windows Media Audio), tambin es posible consumir un formato ms comn como el MP3. A continuacin, podemos ver todos los formatos soportados. WMA 7: Windows Media Audio 7. WMA 8: Windows Media Audio 8. WMA 9: Windows Media Audio 9. WMA 10: Windows Media Audio 10. MP3: ISO/MPEG Layer-3.

En nuestro proyecto, si queremos reproducir msica o sonido, deberemos declarar el control MediaElement de la siguiente forma:
<Grid x:Name=LayoutRoot Background=White> <MediaElement x:Name=Musica Source=Musica/Ghosts.mp3> </MediaElement> </Grid>

RRR

RUTAS

Para acceder a un archivo, no deberemos usar rutas que incluyan identificadores tales como C:\Directorio\Archivo, sino que accederemos a los archivos como si se tratara de un recurso web, utilizando slo rutas relativas al punto de origen de la aplicacin Silverlight.

188

MediaElement

Debemos tener sumo cuidado al momento de colocar la ruta del recurso de sonido por reproducir, ya que se requiere de una ruta relativa a la posicin donde se encuentra el resultado de nuestra aplicacin Silverlight. Esto quiere decir que, si el archivo de sonido se encuentra a la misma altura en el rbol de directorios que nuestra aplicacin, slo necesitaremos colocar el nombre del elemento que se reproducir. Pero, si ste est en alguna ruta ms profunda, deberemos colocar la ruta desde el punto inicial de nuestra aplicacin en adelante. En el cdigo anterior, vemos que el sonido por reproducir se encuentra dentro de la carpeta Musica a partir de la posicin del archivo compilado, como se muestra en la siguiente figura.

Figura 1. rbol de la solucin con la estructura deseada.

El control MediaElement nos puede brindar informacin de lo que est reproduciendo, as como lo que est cargando desde alguna direccin. Tengamos en cuenta que las pruebas que podamos hacer de forma local cargarn mucho ms rpido que si consumiramos los archivos desde Internet. Por este motivo, debido a la velocidad de carga, este control puede avisarnos el estado de sta, as como la finalizacin de carga del archivo en cuestin, para poder presentar informacin al

RRR

ADICIN DE ARCHIVOS

Tanto sea de video como de sonido el archivo que estamos agregando a nuestro proyecto Silverlight, debemos configurar ste para que sea copiado junto con el resultado de la aplicacin cada vez que la compilemos. Podemos conseguir esta accin seleccionando el archivo y modificando la propiedad Copiar en el directorio de resultados, colocndola en Copiar siempre.

189

6. CERRAR EL CRCULO

usuario sobre estos estados. Si agregamos un control TextBlock, podremos brindar informacin al usuario sobre el estado de reproduccin del archivo.
<Grid x:Name=LayoutRoot Background=White> <TextBlock x:Name=Tiempo VerticalAlignment=Top HorizontalAlignment=Center></TextBlock> <MediaElement x:Name=Musica Source=Musica/Ghosts.mp3> </MediaElement> </Grid>

Luego, crearemos un temporizador que inspeccionar de manera continua el valor de la propiedad Position del control MediaElement, y mostrar el progreso de la reproduccin del archivo en el TextBlock antes declarado.
DispatcherTimer reloj; public Page() { InitializeComponent(); reloj = new DispatcherTimer(); reloj.Tick += new EventHandler(reloj_Tick); reloj.Interval = TimeSpan.FromSeconds(0.1); reloj.Start(); } void reloj_Tick(object sender, EventArgs e) { this.Tiempo.Text = Tiempo transcurrido: + this.Musica.Position.TotalSeconds.ToString(); }

_`

MP3 GRATUITOS

En los ejemplos usamos MP3 del lbum Ghost del grupo Nine Inch Nails. Este CD es provisto por la banda de manera gratuita y es de libre uso y distribucin. A pesar de esto, ha generado excelentes ganancias. Este lbum puede ser descargado desde la pgina http://ghosts.nin.com.

190

MediaElement

El resultado del cdigo anterior podemos observarlo en la Figura 2, donde el contador se actualiza constantemente basado en el progreso de reproduccin del archivo MP3. Como vemos, el control MediaElement posee todas las caractersticas necesarias para administrar estos tipos de archivos.

Figura 2. Aqu podemos ver la cantidad de segundos transcurridos en la reproduccin del archivo..

Es posible extender un poco ms nuestro ejemplo para controlar con profundidad la reproduccin del archivo. Agreguemos algunos controles Slider, CheckBox y Button para manipular la reproduccin del archivo MP3.
<Grid x:Name=LayoutRoot Background=White> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> </Grid.ColumnDefinitions> <TextBlock x:Name=Tiempo VerticalAlignment=Bottom HorizontalAlignment=Left Grid.Row=1 Margin=123,0,0,13/> <MediaElement x:Name=Musica Source=Musica/Ghosts.mp3 Grid.Row=1 AutoPlay=False MediaOpened=Musica_MediaOpened />

191

6. CERRAR EL CRCULO

<Button HorizontalAlignment=Left Margin=105,8,0,0 VerticalAlignment=Top Grid.Row=2 Content=Reproducir d:LayoutOverrides=Height Click=Button_Click/> <Button Margin=184,8,162,0 VerticalAlignment=Top Grid.Row=2 Content=Detener d:LayoutOverrides=Height Click=Button_Click_1/> <Button HorizontalAlignment=Right Margin=0,8,114,0 VerticalAlignment=Top Grid.Row=2 Content=Parar d:LayoutOverrides=Width, Height Click=Button_Click_2/> <CheckBox HorizontalAlignment=Left VerticalAlignment=Bottom Content=Silenciar d:LayoutOverrides=Height Click=CheckBox_Click x:Name=Silencio/> <Slider Margin=105,26,114,31 Grid.Row=1 d:LayoutOverrides=Height x:Name=Progreso ValueChanged=Progreso_ValueChanged/> </Grid>

Para cada accin o evento necesitamos crear su manejador en el cdigo C#. Tambin notaremos, en el siguiente cdigo, que hemos asignado valores al control Slider sobre la base de las caractersticas del archivo por reproducir.
DispatcherTimer reloj; public Page() { InitializeComponent(); reloj = new DispatcherTimer(); reloj.Tick += new EventHandler(reloj_Tick); reloj.Interval = TimeSpan.FromSeconds(0.1); reloj.Start(); } void reloj_Tick(object sender, EventArgs e) { this.Tiempo.Text = Tiempo transcurrido: + this.Musica.Position.TotalSeconds.ToString(); this.Progreso.Value = this.Musica.Position.TotalSeconds; }

192

MediaElement

private void Musica_MediaOpened(object sender, RoutedEventArgs e) { this.Progreso.Maximum = this.Musica.NaturalDuration.TimeSpan.TotalSeconds; } private void Button_Click(object sender, RoutedEventArgs e) { this.Musica.Play(); } private void Button_Click_1(object sender, RoutedEventArgs e) { this.Musica.Pause(); } private void Button_Click_2(object sender, RoutedEventArgs e) { this.Musica.Stop(); } private void Progreso_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { this.Musica.Position = TimeSpan.FromSeconds(this.Progreso.Value); } private void CheckBox_Click(object sender, RoutedEventArgs e) { this.Musica.IsMuted = (bool)this.Silencio.IsChecked; }

RRR

MS DE MICROSOFT EXPRESSION BLEND

Microsoft pone nuestra disposicin un sitio web en el que se ensean tcnicas avanzadas en el uso del producto Microsoft Expression Blend. En este sitio, podremos aprender tcnicas para optimizar el uso de videos, la aplicacin de efectos y movimiento sobre los objetos XAML y hasta la interfaz de esta aplicacin. En http://expression.microsoft.com buscamos Learn Expression Blend.

193

6. CERRAR EL CRCULO

Figura 3. Nuestro reproductor de MP3 en el que podremos iniciar, pausar y detener la reproduccin, as como saltar a cualquier posicin del sonido, incluso, silenciarlo si es necesario.

Video
Iniciamos el captulo con la reproduccin de sonidos y msica, ya que era un punto pendiente si tenemos en cuenta el ejemplo creado en el captulo 2. A pesar de esto, el tratamiento de video con el control MediaElement tiene an ms que ofrecer. Si bien no es competencia de este libro hablar de las caractersticas del streaming de videos desde servidores web, s veremos cmo Silverlight nos brinda soporte para esto mediante el control MediaElement, pudiendo aplicar el video sobre superficies, leer y reconocer la informacin contenida en l, entre otras caractersticas. En la actualidad, el control MediaElement soporta la reproduccin de los siguientes formatos de video: WMV1: Windows Media Video 7. WMV2: Windows Media Video 8. WMV3: Windows Media Video 9. WMVA: Windows Media Video Advanced Profile, non-VC-1. WMVC1: Windows Media Video Advanced Profile, VC-1.

Como podemos notar, los formatos de video son los provistos por Microsoft y se centran en el WMV (Windows Media Video). Por este motivo, es necesario contar con algn convertidor de video a la hora de querer reproducir video con Silverlight. Encontraremos variadas herramientas tiles para esto, como Windows Movie Maker incluida en la mayora de las versiones de Windows, o, dentro del conjunto de herramientas Expression, Microsoft Expression Encoder 2.
194

MediaElement

Elementos con video embebido


Ya sabemos que XAML se basa en XML para representar los distintos elementos y, por tal motivo, as como es posible en XML anidar elementos, tambin es posible hacerlo con XAML. En el caso del video, podemos extender las funcionalidades de visualizacin mucho ms all de la simple representacin de una pelcula en un rectngulo: es posible reproducir video dentro de otros elementos, los que actuarn como una mscara. As, si tenemos texto con un video dentro de ste, el video ser visible por sobre el texto, mostrando slo las partes que comprendan la frase o palabras de dicho elemento. Esta caracterstica la conseguimos mediante el uso del elemento VideoBrush, y podemos implementarlo como sigue.
<MediaElement x:Name=Video Source=SilverLightConMarcadores.wmv Width=100 Height=50 HorizontalAlignment=Left Margin=7.915,8,0,0 VerticalAlignment=Top/> <TextBlock HorizontalAlignment=Left Margin=8.085,72,0,0 VerticalAlignment=Top Width=340.711 FontSize=48 Text=Video en texto con SilverLight TextWrapping=Wrap FontWeight=Bold FontFamily=Comic Sans MS> <TextBlock.Foreground> <VideoBrush SourceName=Video></VideoBrush> </TextBlock.Foreground> </TextBlock>

En el cdigo anterior, creamos un elemento MediaElement para reproducir un video. Esto es necesario para poder utilizar el tag VideoBrush, ya que ste necesita de un componente con la capacidad de reproduccin de video para visualizar ese video. Pensemos en VideoBrush como la posibilidad de pintar en cualquier superficie lo que el control MediaElement est reproduciendo en este momento. En este caso, el video se pintar sobre el color de fondo del control TextBlock. Pero no slo es posible aplicarlo sobre este control ya que, como dijimos, VideoBrush es una forma de

RRR

FORMATOS DE VIDEO

Si bien la versin 2 de Silverlight puede resultar limitada en la cantidad de formatos posibles para reproduccin de video, la siguiente versin de Silverlight, Silverlight 3, contar con pleno soporte para los formatos de video ms conocidos, incluidos los utilizados por Adobe Flash y QuickTime.

195

6. CERRAR EL CRCULO

pintar un video sobre otros elementos, sino que podramos aplicarlo sobre cualquier otro control que posea propiedades de pintado. Como vemos en el siguiente cdigo, pintamos el mismo video sobre la superficie de un control Button.
<Button HorizontalAlignment=Left VerticalAlignment=Bottom Content=Button Margin=8.085,0,0,23 Height=52 Width=131> <Button.Background> <VideoBrush SourceName=Video></VideoBrush> </Button.Background> </Button>

Notemos que VideoBrush utiliza la propiedad SourceName para especificar el nombre del control MediaElement desde donde obtendr la fuente de video. Esto quiere decir que todos los cambios que nosotros realicemos al control MediaElement tambin afectarn a los elementos VideoBrush que pudiramos tener en nuestra aplicacin.

Figura 4. Video sobre diferentes objetos.

Marcadores de video
Cuando trabajamos con videos, existe la posibilidad de agregarles marcas con identificaciones especiales. Estas marcas, en ocasiones, son usadas para hacer avanzar el video hasta la marca en cuestin y darle la posibilidad al usuario de elegir el punto para comenzar a visualizar el video. El control MediaElement puede leer las marcas en los videos para otorgar la misma posibilidad, esto es, desplazar el video hasta el punto en el que se encuentre esa marca. El primer paso para trabajar con marcadores es poder reconocerlos.
196

MediaElement

El control MediaElement posee un evento que nos avisar cada vez que pase por un marcador. En el siguiente cdigo, hacemos uso de este evento para mostrar los marcadores incluidos en el video:
<MediaElement Source=SilverLightConMarcadores.wmv Width=300 Margin=50,25,50,84 MarkerReached=MediaElement_MarkerReached/> <TextBlock x:Name=TextoMarcas VerticalAlignment=Bottom Text= TextWrapping=Wrap Margin=8,0,8,8 Height=59/>

Cada vez que se pase por un marcador, se disparar el evento MarkerReached, escribiendo la descripcin y la posicin de tiempo en la que se encuentra esta marca.
private void MediaElement_MarkerReached(object sender, TimelineMarkerRoutedEventArgs e) { this.TextoMarcas.Text = Nombre del marcador: + e.Marker.Text + , encontrado en + e.Marker.Time.Minutes.ToString() + : + e.Marker.Time.Seconds.ToString(); }

En la figura que aparece a continuacin, podemos ver cmo se despliega la marca del video en el momento de alcanzarla.

Figura 5. Marca alcanzada mientras se reproduce el video.


197

6. CERRAR EL CRCULO

Ya que podemos detectar cada marca, sera sencillo reconocer todos los marcadores de un video para presentrselos al usuario y que ste pueda saltar entre ellos y as navegar con mayor facilidad dentro de la reproduccin en curso.
TimelineMarker miMarcador; private void MediaElement_MediaOpened(object sender, RoutedEventArgs e) { miMarcador = this.Video.Markers[0]; } private void Button_Click(object sender, RoutedEventArgs e) { this.Video.Position = miMarcador.Time; this.Video.Play(); }

Vemos, en el cdigo anterior, que en el evento MediaOpened, disparado en el momento en que el video es cargado totalmente, leemos los marcadores. Si bien stos pueden ser una lista, slo tomaremos el primero que encontramos, almacenndolo en un objeto del tipo TimelineMarker. Luego, por medio del evento Click de un botn, usamos el valor de tiempo de este marcador para reposicionar la reproduccin del video. Como vemos a continuacin, al presionar el botn, el video vuelve al punto de la marca.

Figura 6. A la izquierda, el video retrocedi hasta la marca. A la derecha, el video se ejecuta de manera continua.
198

Deep Zoom

tiene an mucho ms por ofrecer y, por esto, iremos develando sus caractersticas en los siguientes captulos. De cualquier manera, en este punto nos habremos dado cuenta de que la potencia de Silverlight y el manejo de elementos multimedios no son una limitacin, sino que, por el contrario, pueden darnos muchas ventajas en el desarrollo de aplicaciones.
MediaElement

DEEP ZOOM
El concepto de Deep Zoom es el de proveer una herramienta para manipular imgenes de gran tamao dentro de las aplicaciones Silverlight, con el objetivo de aligerar la transmisin de ellas al cliente. Adems de esto, permite agregar funcionalidades de acercamiento gradual o zoom. Pensemos en Deep Zoom como en una tcnica que despliega imgenes para el cliente, quien puede acercarse y observar los detalles de estas imgenes sobre la base de su resolucin. As, si contamos con imgenes de alta definicin, que por lo general son de varios megabytes, transmitiremos toda la imagen con el mximo de sus detalles segn la demanda de informacin que el cliente requiera, sin tener que mover toda la imagen hasta el cliente desde el principio, lo que significara lentitud en la carga de la aplicacin y un elevado consumo de recursos para la transmisin de los datos. Si bien existe en el mercado este tipo de tecnologa y no podramos decir que es nueva, Deep Zoom marca una diferencia en la forma en cmo es presentada la informacin. Esto se debe a que, en lugar de mostrar diferentes imgenes basadas en el grado de zoom que realicemos, Deep Zoom transmitir la imagen actual de acuerdo con el rango de visin, con la mejor resolucin posible, haciendo un balance entre calidad y costo de la transmisin de informacin hacia el cliente. De esta forma, no veremos saltos entre cada uno de los grados de zoom y siempre obtendremos una imagen de alta calidad obtenida desde la imagen original. Si queremos empezar a trabajar con Deep Zoom, necesitaremos descargar la aplicacin Deep Zoom Composer desde el sitio web de Microsoft. Deep Zoom Composer no tienen ningn costo asociado, por lo que podremos descargarlo y usarlo libremente.

_`

UNO DE LOS PRIMEROS DEEP ZOOM

Hard Rock Cafe fue uno de los primeros sitios en utilizar la tecnologa Deep Zoom. La empresa lo implement en su web para que los usuarios pudieran ver la coleccin de objetos, cartas, instrumentos y otros elementos que poseen y que fueran entregados por diferentes artistas de la msica. Podemos ver el sitio de Memorabilia en http://memorabilia.hardrock.com.

199

6. CERRAR EL CRCULO

Crear el primer Deep Zoom


Para crear un componente Deep Zoom, necesitamos una o varias imgenes, preferentemente de alta definicin, y haber instalado la aplicacin Deep Zoom Composer. Una vez que consigamos esto, el primer paso es crear una aplicacin nueva.

Figura 7. Creacin de un nuevo proyecto con Deep Zoom Composer.

Hasta la fecha, Deep Zoom Composer slo se encuentra disponible en idioma ingls. A pesar de esto, su uso resulta simple e intuitivo, por lo que no tendremos problemas en entender los pasos de la creacin de este tipo de proyectos. Entonces, presionamos sobre la opcin New Project. Al hacerlo, veremos la ventana para la creacin del nuevo proyecto, donde introduciremos su nombre y la ruta fsica donde se alojar. Con el proyecto creado, necesitamos completar tres pasos antes de obtener el producto final. El primero es la importacin de imgenes a partir del botn Import, ubicado en la parte superior. Podremos importar tantas como necesitemos y, si bien uno de los pasos es acomodar estas imgenes segn cmo queramos que se visualicen, es recomendable, en caso de tener mltiples imgenes que juntas formen una sola, utilizar otras herramientas externas de composicin de imgenes para unirlas en una, ya que Deep Zoom Composer slo nos proveer de elementos bsicos para hacer este trabajo. Una vez adicionadas las imgenes, stas aparecern en la lista de la derecha.

RRR

DEEP ZOOM COMPOSER

Tenemos la posibilidad de descargar DeepZoom Composer desde el sitio de descargas de Microsoft (www.microsoft.com/downloads). All, podremos acceder a la descarga realizando una bsqueda con el nombre de la aplicacin dentro del sitio web de Microsoft.

200

Deep Zoom

Figura 8. En este caso, adicionamos una imagen al proyecto.

El siguiente paso de nuestro trabajo consiste en la composicin de las imgenes y cmo estarn distribuidas en las aplicacin Deep Zoom. Presionando en el botn Compose, ubicado en la parte superior de Deep Zoom Composer, accederemos al siguiente paso. Arrastrando las imgenes al lienzo de trabajo, colocaremos cada una de ellas en la posicin en la que queremos que se visualicen, como se muestra en la figura que aparece a continuacin.

Figura 9. Una imagen ubicada en el centro de Deep Zoom.


201

6. CERRAR EL CRCULO

El ltimo paso consiste en generar el proyecto exportndolo al formato que pueda entender Silverlight. Para esto, presionamos sobre la ltima opcin de las tres superiores, llamada Export. Al hacer esto, tendremos que elegir el formato de exportacin del proyecto. Si necesitamos ver un ejemplo completo de la implementacin de Deep Zoom basado en nuestro proyecto, podremos elegir la opcin Silverlight Deep Zoom. sta crear un proyecto completo Silverlight que incluya botones para realizar zooms y movimientos sobre las imgenes incluidas en l. Si, por el contrario, tenemos cierta experiencia en la inclusin del resultado de Deep Zoom Composer en aplicaciones Silverlight, elegiremos la opcin Images para que la aplicacin cree slo los archivos necesarios para que incluyamos, por nuestra cuenta, el proyecto Deep Zoom en nuestra aplicacin Silverlight. Tambin es posible elegir la calidad de la representacin de las imgenes que se van a mostrar. En la Figura 10, en la parte inferior derecha, vemos las opciones de compresin de imagen. Esta compresin modifica el resultado de las imgenes del archivo Deep Zoom resultante. Modificar estos valores podra acelerar el proceso de descarga de las imgenes hacia el cliente, pero al mismo tiempo, un alto nivel de compresin podra deteriorar la calidad de las imgenes.

Figura 10. Vista final de Deep Zoom Composer para la exportacin del proyecto.

Una vez que el proyecto fue generado y, dependiendo de las opciones que hubiramos elegido para generarlo, se nos presentar la opcin de acceder al resultado. Esta opcin nos llevar a la carpeta con los resultados del proyecto. El proyecto en s es representado por un conjunto de archivos entre los que se encuentran los diferentes muestreos de imgenes relacionados con las imgenes utilizadas para crear el proyecto Deep Zoom, adems de archivos XML con meta datos.
202

Deep Zoom

Figura 11. Resultado del proyecto Deep Zoom.

Incluir Deep Zoom en Silverlight


Para incrustar el resultado del proyecto Deep Zoom en Silverlight, crearemos un nuevo proyecto Silverlight seleccionando la opcin para que Visual Studio 2008 cree un sitio web adicional para ejecutar el proyecto (podemos recurrir al captulo 3 para recordar este paso). Una vez creado, deberemos ver el rbol de la solucin.

Figura 12. Proyecto Silverlight junto a un proyecto web para depuracin.

Notaremos que el proyecto web contiene una carpeta llamada ClientBin. Esta carpeta es la contenedora de los resultados que obtenemos luego de la compilacin
203

6. CERRAR EL CRCULO

de la aplicacin Silverlight y es el lugar donde se ubicar fsicamente nuestra aplicacin. Por eso, para tener acceso al contenido del proyecto Deep Zoom, all tendremos que colocar todos los archivos resultantes de Deep Zoom. Podemos ver un ejemplo de esta accin en la siguiente figura.

Figura 13. En el rbol de soluciones, vemos los archivos del proyecto Deep Zoom.

Una vez que tenemos los archivos en su lugar, usaremos el control MultiScaleImage para desplegarlas en el proyecto. Podemos ver un ejemplo a continuacin.
<UserControl x:Class=Capitulo6MiDeepZoom.Page xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml Width=400 Height=300> <Grid x:Name=LayoutRoot Background=White> <MultiScaleImage x:Name=MiDeepZoom Width=350 Height=250 Source=mideepzoom/dzc_output.xml></MultiScaleImage> </Grid> </UserControl>

Observemos que el motivo por el que colocamos el proyecto Deep Zoom dentro de la misma carpeta donde se despliega el resultado de la aplicacin Silverlight es para que resulte ms simple poder accederla. Tambin es importante el archivo al cual se hace referencia, que es dzc_output.xml, archivo que contiene los metadatos del proyecto, como lista de imgenes y direcciones, entre otros.
204

Deep Zoom

El paso que hicimos slo mostrar el proyecto si desplegamos el estado inicial que hubiramos configurado en el momento de crear el proyecto en Deep Zoom Composer. Necesitaremos hacer algo de cdigo para crear la interaccin con las imgenes y que el comportamiento de Deep Zoom se haga presente. Primero, modificaremos un poco el cdigo XAML para incluir llamadas a los eventos que se relacionan con el mouse.
<Grid x:Name=LayoutRoot Background=White MouseMove=LayoutRoot_MouseMove MouseLeftButtonDown=LayoutRoot_MouseLeftButtonDown MouseLeftButtonUp=LayoutRoot_MouseLeftButtonUp> <MultiScaleImage x:Name=MiDeepZoom Width=350 Height=250 Source=mideepzoom/dzc_output.xml MouseLeave=MiDeepZoom_MouseLeave></MultiScaleImage> </Grid>

Estos eventos se dispararn cuando el botn izquierdo del ratn sea presionado, cuando se mueva e, incluso, cuando deje la zona en la que se est presentando el proyecto Deep Zoom. Cada uno de estos eventos tendr el cdigo asociado como podemos ver a continuacin:
private private private private private private bool RatonPresionado; bool RatonArrastrando; Point UltimaPosicionRaton; Point DesfaseArrastre; Point PosicionActual; double FactorZoom;

private void MiDeepZoom_MouseLeave(object sender, MouseEventArgs e) { RatonArrastrando = false; } private void LayoutRoot_MouseMove(object sender, MouseEventArgs e) { if (RatonPresionado) { RatonArrastrando = true; } this.UltimaPosicionRaton = e.GetPosition(this.MiDeepZoom);

205

6. CERRAR EL CRCULO

if (RatonArrastrando) { Point newOrigin = new Point(); newOrigin.X = PosicionActual.X - (((e.GetPosition(MiDeepZoom).X DesfaseArrastre.X) / MiDeepZoom.ActualWidth) * MiDeepZoom.ViewportWidth); newOrigin.Y = PosicionActual.Y - (((e.GetPosition(MiDeepZoom).Y DesfaseArrastre.Y) / MiDeepZoom.ActualHeight) * MiDeepZoom.ViewportWidth); MiDeepZoom.ViewportOrigin = newOrigin; } } private void LayoutRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { RatonPresionado = true; RatonArrastrando = false; DesfaseArrastre = e.GetPosition(this); PosicionActual = MiDeepZoom.ViewportOrigin; } private void LayoutRoot_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { RatonPresionado = false; if (RatonArrastrando == false) { bool shiftApretado = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift; FactorZoom = 2.0;

RRR

MANEJO DE LA RUEDA DEL MOUSE

Si necesitamos saber cmo manejar la rueda del mouse para realizar zoom, podemos generar un proyecto Deep Zoom con Deep Zoom Composer, que tambin genere un proyecto Silverlight para incluir el resultado de Deep Zoom. El cdigo generado por Deep Zoom Composer nos otorgar excelente cdigo de ejemplo para nuestras implementaciones.

206

Deep Zoom

if (shiftApretado) FactorZoom = 0.5; Zoom(FactorZoom, this.UltimaPosicionRaton); } RatonArrastrando = false; } public void Zoom(double zoom, Point pointToZoom) { Point puntoLogico = this.MiDeepZoom.ElementToLogicalPoint(pointToZoom); this.MiDeepZoom.ZoomAboutLogicalPoint(zoom, puntoLogico.X, puntoLogico.Y); }

El cdigo anterior puede resultar confuso a primera vista, pero todo se reduce al mtodo ZoomAboutLogicalPoint provisto por el control MultiScaleImage. Este mtodo es el encargado de generar el efecto de zoom basado en un factor de zoom, tanto positivo como negativo, as como sobre la base de un punto XY. Este mtodo se ejecuta en el mtodo Zoom del cdigo anterior, ya que las dems lneas de cdigo se encargan de administrar el estado del mouse antes de realizar alguna accin. Si ejecutamos el proyecto, veremos que al presionar sobre la imagen se realizar el acercamiento a ella, mientras que si lo hacemos presionando la tecla SHIFT (maysculas) al mismo tiempo que pulsamos el botn del mouse, la imagen se alejar. A continuacin, un ejemplo.

Figura 14. Observamos, en cada navegador, el resultado de interactuar con la aplicacin Deep Zoom.
207

6. CERRAR EL CRCULO

DIBUJAR CON INKPRESENTER


Silverlight trae consigo otros complementos, en especial, interesantes. Uno de estos es InkPresenter, un componente que facilita la escritura manual sobre cualquier aplicacin Silverlight. Si bien el modelo de escritura a mano puede estar ligado con los dispositivos mviles inteligentes como Pocket PCs o Tablet PCs, Silverlight incorpora esta capacidad tambin, pudiendo enriquecer an ms el conjunto de funcionalidades ofrecidas hasta el momento. Existen casos dentro del desarrollo de aplicaciones empresariales donde puede ser necesario el reconocimiento de firmas electrnicas, que son almacenadas en bases de datos y comparadas luego para su validacin. Tambin podra ser interesante brindarle al usuario la posibilidad de enviar tarjetas electrnicas escritas por l, dejando de lado el texto plano automatizado que, por lo comn, suele emplearse para este tipo de aplicaciones. Entonces, InkPresenter es un control en Silverlight que nos otorgar una superficie de dibujado a mano haciendo uso del mouse, donde podremos capturar lo escrito, almacenarlo y procesarlo para su posterior uso. Adems, InkPresenter viene acompaado de un conjunto de APIs (Application Programming Interfaces o en castellano, interfaz para programacin de aplicaciones) para el reconocimiento de los patrones introducidos por el usuario y su transformacin en texto plano legible. Veamos la declaracin de un elemento InkPresenter desde cdigo XAML.
<InkPresenter></InkPresenter>

El tag XAML del control InkPresenter agregar el lienzo de dibujo a nuestra aplicacin, y slo podremos dibujar sobre l. Por este motivo, el control InkPresenter deber estar declarado por encima de cualquier otro elemento. Si algn otro componente se dibujara sobre el control InkPresenter, no podramos visualizarlo y tampoco escribir sobre l, ya que los eventos relacionados con la captura de informacin no seran alcanzados. Para entender esto, pensemos en capas u hojas de dibujo. La capa superior y visible, la ms cercana al usuario, es la que puede interactuar con l, capturando cualquier tipo de accin que el usuario realice, dejando a las capas

RRR

COLORES

Los tipos de datos para colores en XAML son representados en formato hexadecimal, de manera similar al utilizado en HTML, con la diferencia de que, en Silverlight, se incluye un par de nmeros iniciales para especificar el nivel de transparencia de ese color. Si contamos con #FF000000, obtenemos un color negro pleno y sin transparencias.

208

Dibujar con InkPresenter

inferiores fuera del alcance de estos eventos. Por eso, deberemos asegurarnos de que el control InkPresenter se posicione sobre la capa superior y ms cercana al usuario. Veamos, ahora, la declaracin completa del control InkPresenter.
<Grid x:Name=LayoutRoot Background=White> <InkPresenter x:Name=inkPresenter Background=#FFCBD8E4 Margin=8,8,8,8 Opacity=1 MouseLeftButtonDown=inkPresenter_MouseLeftButtonDown MouseMove=inkPresenter_MouseMove LostMouseCapture=inkPresenter_LostMouseCapture/> </Grid>

Figura 15. Podemos ver el lienzo de InkPresenter incorporado en nuestro proyecto.

Del cdigo anterior, los atributos destacables son los tres eventos relacionados con la accin de escritura. A continuacin, veamos sus detalles: MouseLeftButtonDown: este evento se refiere al momento en el que el usuario presiona el botn izquierdo del mouse. En este evento, inicializaremos la captura de informacin del control InkPresenter. MouseMove: cada vez que el usuario mueva el mouse sobre el lienzo de InkPresenter, este evento se disparar. Al dispararse, guardaremos la informacin capturada para que sea mostrada en el lienzo. LostMouseCapture: en el momento en que el botn del mouse sea liberado o el control deje de percibir informacin desde el usuario, este evento ser disparado.
209

6. CERRAR EL CRCULO

Figura 16. Aqu, podemos ver el control InkPresenter en accin.

Antes de comenzar a crear cdigo para poder dibujar sobre InkPresenter, es necesario configurar los lmites de dibujo ya que, si bien el control representa un elemento rectangular, podemos especificar los espacios donde se podr escribir o no. Esto puede resultar muy verstil cuando necesitamos adaptar las caractersticas de dibujo a una zona en particular.
public Page() { InitializeComponent(); Limites(); } private void Limites() { RectangleGeometry Rectangulo = new RectangleGeometry(); Rectangulo.Rect = new Rect(0, 0, this.inkPresenter.Width, this.inkPresenter.Height); this.inkPresenter.Clip = Rectangulo; }

Los lmites elegidos en este caso son representados por un rectngulo con el mismo tamao que el control InkPresenter. Esto har que podamos escribir sobre toda la superficie del control libremente. El siguiente paso es escribir el cdigo detrs de cada uno de los eventos antes mencionados.
210

Dibujar con InkPresenter

private Stroke pincel; private void inkPresenter_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { this.inkPresenter.CaptureMouse(); StylusPointCollection ColeccionDeEstilos = new StylusPointCollection(); ColeccionDeEstilos.Add(e.StylusDevice.GetStylusPoints(this.inkPresenter)); pincel = new Stroke(ColeccionDeEstilos); this.inkPresenter.Strokes.Add(pincel); }

Dentro del cdigo anterior, en el evento MouseLeftButtonDown, iniciamos la captura del mouse, adems de configurar el tipo de pincel que se va a utilizar para realizar el dibujo. Por defecto, este pincel ser bsico y de color negro. Por su parte, el segundo evento se encargar de analizar las coordenadas del mouse a medida que ste se desplaza por el control.
private void inkPresenter_MouseMove(object sender, MouseEventArgs e) { if (pincel != null) pincel.StylusPoints.Add(e.StylusDevice.GetStylusPoints(this.inkPresenter)); }

Como vemos en este cdigo, es necesario verificar que el pincel haya sido creado antes de capturar los trazos generados por el mouse. Si no hiciramos esto, el usuario, al mover el mouse, creara trazos continuos. Por ltimo, incorporamos el cdigo relacionado al ltimo evento.
private void inkPresenter_LostMouseCapture(object sender, MouseEventArgs e) { pincel = null; }

Una vez que el botn del mouse es liberado, el pincel se elimina, haciendo que ya no se dibujen los movimientos del usuario sobre el control.
211

6. CERRAR EL CRCULO

Dibujar en forma manual


Como ya dijimos, InkPresenter representa trazos creados por el usuario. Estos trazos no slo pueden ser introducidos por el usuario, sino que es posible que nosotros proveamos estos elementos desde el comienzo. La realizacin de este trabajo nos lleva a la posibilidad de guardar informacin de trazos generados por el usuario y, luego, mostrarlos sin intervencin de su parte.

Figura 17. Trazos creados con XAML.

Como vemos en la figura anterior, el control InkPresenter puede mostrar trazos basados en tags creados de manera manual. Veamos, a continuacin, el cdigo XAML:
... ... <InkPresenter.Strokes> <StrokeCollection> <Stroke> <Stroke.DrawingAttributes> <DrawingAttributes Color=#FF000000 Width=5 Height=5 /> </Stroke.DrawingAttributes> <Stroke.StylusPoints> <StylusPoint X=10 Y=10 /> <StylusPoint X=100 Y=10 />

212

Dibujar con InkPresenter

<StylusPoint X=100 Y=100 /> <StylusPoint X=10 Y=100 /> <StylusPoint X=10 Y=10 /> </Stroke.StylusPoints> </Stroke> </StrokeCollection> </InkPresenter.Strokes> </InkPresenter>

Cada tag <Stroke> dentro del tag <StrokeCollection> representa un trazo nico. Esto es el equivalente a que el usuario hubiera creado dicho trazo sin dejar de presionar el botn del mouse. El tag <Stroke.DrawingAttributes> representa la caracterstica del trazado. En el ejemplo, ste muestra un grosor de 5 pixeles de ancho y 5 pixeles de alto, adems de ser de color negro. Por ltimo, encontramos cada uno de los puntos del trazo representados por la coleccin <Stroke.StylusPoints>, que contendr cada uno de los puntos basados en el tag <StylusPoint>, el cual especifica las coordenadas XY donde se inicia el punto. Debido a que ste es un nico trazo, al dibujar ms puntos en diferentes coordenadas, stos se unirnmediante una lnea. Como vemos en la Figura 17, la unin de los puntos deriv en la construccin de un cuadrado. Y as como creamos trazos desde el cdigo XAML, tambin podemos hacerlo desde nuestro cdigo, como observamos en la Figura 18. All, la lnea de color verde es creada desde el cdigo XAML. Esto se logra siguiendo el mismo patrn que el de XAML. El siguiente cdigo muestra cmo generar estos trazos desde cdigo C#.

Figura 18. Trazos creados por cdigo.


213

6. CERRAR EL CRCULO

private void Button_Click(object sender, RoutedEventArgs e) { Stroke trazo = new Stroke(); trazo.DrawingAttributes.Width = 3; trazo.DrawingAttributes.Height = 3; trazo.DrawingAttributes.Color = Color.FromArgb(150, 50, 150, 150); StylusPointCollection coleccionEstilos = new StylusPointCollection(); StylusPoint punto = new StylusPoint(); punto.X = 150; punto.Y = 10; coleccionEstilos.Add(punto); StylusPoint punto2 = new StylusPoint(); punto2.X = 300; punto2.Y = 10; coleccionEstilos.Add(punto2); StylusPoint punto3 = new StylusPoint(); punto3.X = 300; punto3.Y = 100; coleccionEstilos.Add(punto3); trazo.StylusPoints.Add(coleccionEstilos); this.inkPresenter.Strokes.Add(trazo); }

Si comparamos el patrn XAML con el cdigo antes presentado, notaremos sus similitudes. Primero se crea el trazo, especificando el color y el grosor que tendr.
Stroke trazo = new Stroke(); trazo.DrawingAttributes.Width = 3; trazo.DrawingAttributes.Height = 3; trazo.DrawingAttributes.Color = Color.FromArgb(150, 50, 150, 150); ... ...

Luego, creamos el contenedor de la coleccin de puntos por dibujar y adicionamos cada uno de los puntos, como vemos en el siguiente cdigo:
214

Dibujar con InkPresenter

... StylusPointCollection coleccionEstilos = new StylusPointCollection(); StylusPoint punto = new StylusPoint(); punto.X = 150; punto.Y = 10; coleccionEstilos.Add(punto); ...

Dibujar sobre otros elementos


Si seguimos el mismo modelo de dibujo sobre el elemento InkPresenter, veremos que es posible extenderlo para que podamos dibujar sobre cualquier otro control que deseemos. Esto resulta especialmente til sobre controles y componentes con capacidades de desplegar imgenes y videos.

Figura 19. Es posible dibujar sobre una imagen preestablecida.

El control InkPresenter puede contener otros controles, por lo que, para lograr lo visto en la figura anterior, tendremos que agregar el control Image como contenido del control InkPresenter. Veamos cmo hacerlo:
<InkPresenter x:Name=inkPresenter Background=#FFCBD8E4 Margin=8,8,8,8 Opacity=1 Width=384 Height=284

215

6. CERRAR EL CRCULO

MouseLeftButtonDown=inkPresenter_MouseLeftButtonDown MouseMove=inkPresenter_MouseMove LostMouseCapture=inkPresenter_LostMouseCapture> <Image Source=Colinas azules.jpg Width=384 Height=284/> </InkPresenter>

Luego, podremos intercambiar este elemento interno por cualquier otro capaz de representar algn medio visual. El cdigo para escribir sobre video resultar similar al anterior. En este caso, utilizamos un control MediaElement para desplegar el video y escribir sobre l. En la Figura 20 que encontramos debajo podemos ver un ejemplo del resultado que se podra obtener.
<InkPresenter x:Name=inkPresenter Background=#FFCBD8E4 Margin=8,8,8,8 Opacity=1 Width=384 Height=284 MouseLeftButtonDown=inkPresenter_MouseLeftButtonDown MouseMove=inkPresenter_MouseMove LostMouseCapture=inkPresenter_LostMouseCapture> <MediaElement Source=silverlight.wmv AutoPlay=True /> </InkPresenter>

Figura 20. En este caso, utilizamos el mismo concepto para escribir sobre video.
216

Dibujar con InkPresenter

InkPresenter y reas de dibujo


Si bien el control InkPresenter se muestra, por lo general, como un rectngulo, resulta lo bastante verstil como para poder definir reas permitidas para dibujar sobre l. En este caso, el control InkPresenter aparecer con bordes redondeados, y los trazos realizados por el usuario no podrn sobrepasar estos lmites. Para conseguir esto, podemos hacer uso de la propiedad Clip del control. Lo haremos de la misma forma que hemos empleado para asignar un rea rectangular, pero, en este caso, especificaremos una matriz de puntos que representen las esquinas curvas.
<InkPresenter x:Name=inkPresenter Width=300 Height=200 Background=Aqua MouseLeftButtonDown=inkPresenter_MouseLeftButtonDown MouseMove=inkPresenter_MouseMove LostMouseCapture=inkPresenter_LostMouseCapture Clip=M0.5,25.5 C0.5,11.692881 11.692881,0.5 25.5,0.5 L267,0.5 C280.80713,0.5 299,19.192881 299,33 L299,169 C299,182.80713 289.80713,201 276,201 L29,201 C15.192881,201 0.5,186.80713 0.5,173 z />

Figura 21. Aqu podemos ver cmo, al intentar dibujar por sobre las esquinas curvas, la lnea de dibujo no es representada.

Si bien los valores introducidos en la propiedad Clip pueden resultar complejos de entender y de crear en forma manual, Expression Blend 2 nos otorga herramientas para hacerlo de manera visual y ms simple. All, creamos el contorno que vamos a aplicar, y luego copiamos y pegamos el resultado en el control InkPresenter. Primero deberemos agregar un elemento de dibujo al lienzo. Podremos usar elipses o rectngulos. Una
217

6. CERRAR EL CRCULO

vez agregado el elemento, deberemos transformarlo a un tipo de elemento de trazado. Para conseguir esto, presionamos el botn izquierdo del mouse sobre el elemento de dibujo, para seleccionar la opcin Convertir en trazado dentro de Trazado.

Figura 22. Convirtiendo la elipse a un trazado.

Luego de convertir el elemento a trazado, es posible deformarlo a gusto para conseguir la forma que queramos. Por ltimo, aplicaremos este trazado al control InkPresenter.

Figura 23. El trazado completamente modificado.

Para aplicar el trazado, copiaremos el valor del atributo Data del trazado al atributo Clip de InkPresenter. Como resultado, en este caso obtendremos el siguiente cdigo:
218

Dibujar con InkPresenter

<InkPresenter x:Name=inkPresenter Width=300 Height=250 Background=Aqua MouseLeftButtonDown=inkPresenter_MouseLeftButtonDown MouseMove=inkPresenter_MouseMove LostMouseCapture=inkPresenter_LostMouseCapture Clip=M289.97556,99.001045 C255.73196,134.51219 198.63127,225.33125 119.70698,220.46407 C73.678635,217.62555 -25.515903,142.05704 16.996023,143.14827 C35.799923,143.63094 25.502108,94.232025 33.899151,74.349686 C49.08622,38.390076 115.76089,-10.094691 156.73918,49.198044 C206.78326,121.60835 319.49466,68.389313 289.97556,99.001045 z />

Figura 24. El trazo de dibujo slo se aplicar a las zonas preestablecidas en la propiedad Clip.

RESUMEN
Videos, imgenes escalables y capacidades de dibujo; herramientas de Silverlight que pueden enriquecer nuestras aplicaciones de una forma inmensurable. Si los controles y componentes, junto a sus capacidades vistas en captulos anteriores, no nos haban despertado an la imaginacin, poder manipular imgenes de alta resolucin o escribir sobre cualquier superficie es lo que faltaba para romper la barrera de lo tradicional y forzarnos a crear aplicaciones que presenten el contenido de formas antes impensadas.

219

 ACTIVIDADES
PREGUNTAS TERICAS
1 Qu formatos de audio soporta Silverlight 2? 2 Mediante qu mtodos podemos saber la posicin actual de reproduccin de un sonido o msica? 3 Qu mtodo es necesario ejecutar para quitar el sonido por completo de una reproduccin en curso? 3 Recolecte la informacin creada con Ink4 Qu control necesitamos para reproducir video en las aplicaciones Silverlight 2? 4 Con la informacin recolectada en el ejer5 Cules son los formatos de video que pueden ser manejados por Silverlight 2? 6 A qu hace referencia la tecnologa Deep Zoom? 7 Qu control XAML necesitamos utilizar para incluir un elemento Deep Zoom dentro de nuestra aplicacin Silverlight 2? 8 Cul es el objetivo del archivo denominado dzc_output.xml? 9 Cmo se reconocen los trazos creados con InkPresenter desde el cdigo C#? 10 Qu objeto define el tipo de trazo usado por InkPresenter? cicio anterior, trate de volver a mostrarla en la aplicacin Silverlight 2. 5 Teniendo diferentes imgenes, intente crear una presentacin Deep Zoom. Con la informacin que este componente retorna, muestre informacin en una aplicacin Silverlight 2 basada en la imagen que el usuario est visualizando. Presenter y almacnela en formato XML. 2 InkPresenter para Windows Presentation Foundation posee la capacidad de reconocer la escritura y transformarla a letras. Intente implementar esta caracterstica.

EJERCICIOS PRCTICOS
1 Intente reproducir sonidos desde una direccin web remota, haciendo uso del control MediaElement.

220

Silverlight

Captulo

Interconexin
En el ambiente de Internet, aquello que extiende las capacidades de las aplicaciones es la facilidad con la que se puede consumir informacin de distintos medios, incluso fuera de nuestro dominio. Consultar la cotizacin de una moneda o el clima son slo una parte del todo que puede ser construido, y Silverlight no queda exento. Veamos el porqu.
Ampliar las funcionalidades Silverlight desde C# WebClient Enviar informacin Almacenamiento aislado Implementar el almacenamiento aislado Capacidad de almacenamiento Almacenar configuraciones OpenFileDialog Manejo de hilos El concepto de hilos Temporizador Personalizar los hilos Hilos y eventos Consumir servicios desde Silverlight Crear un servicio WCF Manipular datos Enlazado de datos LinQ Resumen Actividades 222 222 230 233 239 240 245 247 251 255 256 257 259 261 263 270 275 276 283 287 288

SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com

7. INTERCONEXIN

AMPLIAR LAS FUNCIONALIDADES


Si bien en los captulos vistos hasta ahora hemos hecho uso de C# para potenciar algunas de las funcionalidades de Silverlight, debemos reconocer que la mayora del trabajo realizado recay sobre el cdigo XAML. Esto se debe a que mucha funcionalidad puede ser creada desde el mismo cdigo XAML, colocando slo algunas gotas de C# como soporte. De cualquier manera, lo que podramos conseguir redunda en los aspectos visuales y no genera mayor interaccin con el usuario que haga uso de nuestra aplicacin Silverlight. Sin embargo, con lneas de cdigo de programacin avanzadas, en Silverlight podemos hacer mucho ms, como conectarnos a servicios web para consumir o enviar informacin, modificar la estructura del cdigo XAML en tiempo de ejecucin o almacenar informacin en el equipo del usuario para utilizarla con posterioridad. En este captulo hablaremos de estas cualidades por medio de ejemplos variados, donde extenderemos la aplicacin Silverlight para que pase de ser un simple visualizador de imgenes y videos, o un contenedor de animaciones, a algo mucho ms robusto y listo para ser usado en mbitos empresariales o con fines tales como el comercio electrnico o, por qu no, hasta la creacin de juegos en la red.

SILVERLIGHT DESDE C#
Es posible que una de las reas ms atractivas del desarrollo de software sea la que se refiere a la creacin de juegos. En sta se suelen aplicar muchas ciencias y tcnicas externas del software, como el uso de la fsica o la matemtica. Al mismo tiempo, en este tipo de desarrollo nos encontramos con acertijos lgicos que desafan nuestro intelecto al tratar de optimizar al mximo el uso de recursos del equipo o para encontrar la mejor forma posible de mover elementos por la pantalla y simular animaciones tpicamente relacionadas con los juegos. Iniciemos, entonces, el uso intensivo de C# para Silverlight con la creacin de un juego. Este juego es bastante conocido y consiste en armar una imagen desplazando cuadrados, que contienen parte de ella, a un nico espacio vaco del tablero de juego. Podremos mover slo una parte a la vez, tratando de formar la imagen previsualizada de manera completa. Primero, crearemos en el cdigo XAML una superficie de dibujado; para esto, necesitaremos de un control Canvas y un control Image donde visualizar la figura correctamente ensamblada.
<UserControl x:Class=Capitulo7ModificacionCanvas.Page xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml Width=810 Height=300

222

Silverlight desde C#

xmlns:d=http://schemas.microsoft.com/expression/blend/2008 xmlns:mc=http://schemas.openxmlformats.org/markup-compatibility/2006 mc:Ignorable=d> <Grid x:Name=LayoutRoot Background=White> <Canvas x:Name=ContenedorJuego /> <Image Source=Froblins4.png Height=300 Width=400 Stretch=Fill HorizontalAlignment=Right d:LayoutOverrides=HorizontalAlignment, Width/> <TextBlock Visibility=Collapsed HorizontalAlignment=Left VerticalAlignment=Top Text=Has Ganado! TextWrapping=Wrap Margin=109,132,0,0 FontSize=20 Width=144.658 FontWeight=Bold FontFamily=Interfaz de usuario porttil x:Name=textblockGanador/> </Grid> </UserControl>

En la Figura 1, vemos cmo se muestra la imagen y, tambin, podemos visualizar el rbol de soluciones, donde notaremos que hemos agregado una imagen a l. Esta imagen ser usada como modelo gua, tanto para que el jugador pueda saber cul es el resultado final por ensamblar, como para que nuestro cdigo tome esta imagen y la desordene en pequeas piezas para crear la esencia del juego.

Figura 1. Primera figura definida en el control Image.

El segundo paso consta de la creacin del tablero de juego. Para esto, crearemos cdigo que cargue la imagen de manera dinmica desde una direccin web dada.
223

7. INTERCONEXIN

public Page() { InitializeComponent(); CrearTablero(); } Canvas[] vectorCanvas = new Canvas[16]; Image[] imagenes = new Image[16]; int[] tablero = new int[16]; private { Uri int for void CrearTablero()

uri = new Uri(Froblins4.png, UriKind.Relative); n = 0; (int x = 0; x < 4; x++) for (int y = 0; y < 4; y++) { n = (x * 4) + y; imagenes[n] = new Image(); imagenes[n].Height = 400; imagenes[n].Width = 400; imagenes[n].Stretch = Stretch.UniformToFill; RectangleGeometry r = new RectangleGeometry(); r.Rect = new Rect((x * 100), (y * 100), 100, 100); imagenes[n].Clip = r; imagenes[n].Source = new BitmapImage(uri); imagenes[n].SetValue(Canvas.TopProperty, Convert.ToDouble(y * 100 * -1)); imagenes[n].SetValue(Canvas.LeftProperty, Convert.ToDouble(x * 100 * -1)); vectorCanvas[n] = new Canvas(); vectorCanvas[n].Width = 100; vectorCanvas[n].Height = 100; vectorCanvas[n].Children.Add(imagenes[n]); vectorCanvas[n].SetValue(Canvas.NameProperty, C + n.ToString()); vectorCanvas[n].MouseLeftButtonDown += new MouseButtonEventHandler(Page_MouseLeftButtonDown); if (n < 15)

224

Silverlight desde C#

this.ContenedorJuego.Children.Add(vectorCanvas[n]); } barajar(); dibujarTablero(); }

Notemos que, por medio del objeto Uri, hacemos referencia a la imagen que se va a cargar, imagen que ser usada para definir el tablero de juego. Luego, con dos bucles, definimos las partes de la imagen, tanto horizontales como verticales. En el bucle interno notamos que, usando la librera de clases de Microsoft .Net, en Silverlight podemos crear nuestras propias imgenes. En este caso, con la siguiente instruccin:
imagenes[n] = new Image();

Esta imagen es configurada con sus dimensiones y posicin. Pero lo importante es representado por el siguiente cdigo:
RectangleGeometry r = new RectangleGeometry(); r.Rect = new Rect((x * 100), (y * 100), 100, 100); imagenes[n].Clip = r;

En l, creamos un nuevo rectngulo de 100 pixeles de ancho por 100 pixeles de alto, desplazndolo una cantidad en X y otra en Y sobre la imagen previamente cargada. Pensemos en esta accin como si estuviramos enfocando slo parte de una imagen ms grande, en la cual desplazamos un rectngulo de visin por sobre una sola seccin de 100 pixeles de ancho por 100 pixeles de alto. Acto seguido, asignamos este rectngulo a la propiedad Clip de la imagen. Recordaremos esta propiedad vista en el captulo anterior, cuando trabajbamos con videos e InkPresenter. Esta propiedad limitar el rea de visin de la imagen slo al rectngulo previamente creado. Al final del mtodo ya descrito, encontramos la llamada a dos mtodos ms, uno para mezclar o barajar las imgenes y otro para dibujar el tablero de juego en el estado actual.
private void barajar() { for (int i = 0; i < 15; i++) {

225

7. INTERCONEXIN

tablero[i] = i; } Random randomizador = new Random(System.DateTime.Now.Second); for (int i = 0; i < 100; i++) { int numero1 = randomizador.Next(15); int numero2 = randomizador.Next(15); if (numero1 != numero2) { int temporal = tablero[numero1]; tablero[numero1] = tablero[numero2]; tablero[numero2] = temporal; } } tablero[15] = -1; } private { int int for { void dibujarTablero() x = 0; y = 0; (int i = 0; i < 15; i++)

x = i / 4; y = i % 4; if (tablero[i] >= 0) { vectorCanvas[tablero[i]].SetValue(Canvas.TopProperty, Convert.ToDouble(y * 100)); vectorCanvas[tablero[i]].SetValue(Canvas.LeftProperty, Convert.ToDouble(x * 100)); } } }

El mtodo barajar() mezclar de forma aleatoria las imgenes, creando un nuevo tablero. Por otro lado, el mtodo dibujarTablero() posicionar cada una de las imgenes sobre la base base del tablero actual. El resultado de esto podemos verlo en la Figura 2, que aparece en la prxima pgina.
226

Silverlight desde C#

Figura 2. La imagen desarmada y lista para que iniciemos el juego.

El paso final es el de darle movimiento e interaccin con el usuario. As, cada vez que el usuario presione una de las imgenes, sta deber ocupar el espacio en blanco contiguo, si lo hubiere, y dejar su espacio libre para que otra imagen pueda ocuparlo.
private void verificarGanador() { bool tableroCompleto = true; for (int i = 0; i < 15; i++) { if (i != tablero[i]) { tableroCompleto = false; break; } } if (tableroCompleto) { //Tenemos un ganador! this.textblockGanador.Visibility = Visibility.Visible; } } private void Page_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {

227

7. INTERCONEXIN

Canvas canvas = sender as Canvas; int identificadorCanvas = -1; int espacioTablero = -1; int espacioVacio = -1; for (int i = 0; i < 16; i++) { if (canvas == vectorCanvas[i]) { identificadorCanvas = i; break; } } for (int i = 0; i < 16; i++) { if (tablero[i] == identificadorCanvas) { espacioTablero = i; } else if (tablero[i] == -1) { espacioVacio = i; } } if ((espacioTablero == espacioVacio + 1) (espacioTablero == espacioVacio (espacioTablero == espacioVacio (espacioTablero == espacioVacio { int x = espacioVacio / 4; int y = espacioVacio % 4; || - 1) || + 4) || - 4))

_`

EL USO DE SILVERLIGHT EN LA WEB

Curiosamente, uno de los sitios ms populares para la visualizacin de videos, YouTube, us los servicios de streaming de Silverlight para transmitir los eventos en vivo de March Madness. Estos eventos pueden ser vistos en la siguiente direccin: www.youtube.com/marchmadness.

228

Silverlight desde C#

vectorCanvas[identificadorCanvas].SetValue(Canvas.TopProperty, Convert.ToDouble(y * 100)); vectorCanvas[identificadorCanvas].SetValue(Canvas.LeftProperty, Convert.ToDouble(x * 100)); tablero[espacioVacio] = identificadorCanvas; tablero[espacioTablero] = -1; verificarGanador(); } }

Podemos notar que el evento donde se captura el presionado del mouse fue enlazado de manera manual en la inicializacin de la aplicacin Silverlight mediante el cdigo que vemos a continuacin:
vectorCanvas[n].MouseLeftButtonDown += new MouseButtonEventHandler(Page_MouseLeftButtonDown);

Debido a eso, esta accin ser capturada por el mtodo antes descrito; mtodo que podemos ver en la siguiente lnea:
private void Page_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { ... ...

En este mtodo, se identifica qu objeto origin el evento de presionado del botn del mouse, buscando en la lista de objetos Canvas cul concuerda con el que ejecut el

UN PASO MS ALL

Slo con agregar un poco ms de funcionalidad al ejemplo planteado, podramos tener un juego an ms complejo. Pensemos en la posibilidad de adicionar una lista de imgenes de las que seleccionar, modificar la dificultad agregando ms divisiones a la imagen, etctera. Nuestro nico lmite es la imaginacin.

229

7. INTERCONEXIN

evento. De esta forma, es posible acceder a sus propiedades, incluida su posicin, y si est contiguo a un espacio en blanco. Al cumplir esta ltima caracterstica, la imagen se mover a ese lugar y se verificar si el tablero se ha formado de manera completa.

Figura 3. Nuestro tablero de juego una vez movidas algunas piezas.

WebClient
El objeto WebClient nos da la posibilidad de enviar y recibir informacin de forma asncrona desde y hacia cualquier destino conformado por una direccin URL (Uniform Resource Locator o en castellano, localizador uniforme de recursos). Con WebClient podramos, por ejemplo, leer informacin de texto que se encuentre en cualquier parte de una web, o conocer noticias en formato RSS (Really Simple Syndication, o en castellano, distribucin simple de contenido). De igual forma, podramos consumir cualquier otro tipo de informacin que nos retornara alguna forma de texto desde la Web. En el siguiente ejemplo, crearemos un lector de noticias en formato RSS, haciendo uso del objeto WebClient y XLinQ para manipular las consultas sobre el contenido. Como primera instancia, crearemos los controles XAML donde se mostrarn los resultados de la consulta.
<UserControl xmlns:data=clrnamespace:System.Windows.Controls;assembly=System.Windows.Controls.Data x:Class=Capitulo7WebClient.Page xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml Width=400 Height=300>

230

Silverlight desde C#

<Grid x:Name=LayoutRoot Background=White> <data:DataGrid x:Name=RssFeed AutoGenerateColumns=True></data:DataGrid> </Grid> </UserControl>

En este ejemplo, usaremos un control DataGrid para mostrar la lista de registros que obtengamos despus de haber consultado la fuente RSS. El siguiente paso es hacer uso del objeto WebClient para lanzar una peticin asncrona a la fuente RSS y tomar el resultado por mostrar.
public Page() { InitializeComponent(); WebClient conectorWeb = new WebClient(); Uri direccionRSS = new Uri(http://feeds2.feedburner.com/redusers); conectorWeb.Encoding = Encoding.UTF8; conectorWeb.DownloadStringCompleted += new DownloadStringCompletedEventHandler(conectorWeb_DownloadStringCompleted); conectorWeb.DownloadStringAsync(direccionRSS); }

Al comienzo, creamos un objeto WebClient que usaremos para conectarnos a la fuente RSS. Tambin es necesaria una instancia del objeto Uri. Este objeto representa una direccin URL fsica y la utilizaremos para especificar el origen de la fuente de datos de la que consumiremos la informacin. WebClient posee una serie de eventos que se dispararn sobre la base de las acciones que realicemos. DownloadProgressChanged: se disparar en el momento en el que una llamada asncrona de descarga de contenidos pueda transferir toda o parte de la informacin. DownloadStringCompleted: se ejecuta siempre que un elemento descargado de manera asncrona se ha descargado por completo. OpenReadCompleted: ocurre cuando una accin de lectura de un recurso de manera asncrona se ha completado. OpenWriteCompleted: se disparar cuando exista una operacin de apertura de un archivo para escribir en l y se haya completado esta accin. UploadProgressChanged: evento que marca cuando parte de una operacin de envo de informacin ha transferido todo o una porcin de los datos.
231

7. INTERCONEXIN

UploadStringCompleted: ocurre cuando finaliza una accin de envo de informacin. WriteStreamClosed: en el momento en que una operacin de escritura se ha completado, este evento se ejecutar. De la lista anterior, usaremos el evento DownloadStringCompleted para que nos avise cundo la informacin se descarg por completo. Al ejecutar el cdigo, podemos ver cmo este evento trae la informacin desde la fuente.

Figura 4. En esta imagen, vemos el modo de depuracin, con los resultados desde la fuente RSS.

A continuacin, colocaremos el siguiente cdigo dentro del mtodo del evento DownloadStringCompleted.
private void conectorWeb_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { XDocument documentoXML = XDocument.Parse(e.Result.ToString()); var RSS = from fuentes in documentoXML.Descendants(item) select new EntidadRSS { Titulo = (string)fuentes.Element(title), Descripcion = (string)fuentes.Element(description), Link = (string)fuentes.Element(link) };

232

Silverlight desde C#

this.RssFeed.ItemsSource = RSS; }

Una vez que la descarga del contenido es ejecutada, tomaremos este contenido desde los argumentos del evento. El objeto e posee una propiedad llamada Result (resultados), donde se encontrar el contenido de la descarga. Este contenido es asignado a un objeto del tipo XDocument, objeto que puede administrar XML para facilitar su manipulacin. Por ltimo, mediante una consulta XLinQ, se toman los datos importantes como ttulo, descripcin e hipervnculo de acceso a la noticia, alojando todos los resultados dentro de una coleccin de objetos del tipo EntidadRSS. sta es una entidad que creamos para este caso y que podemos ver a continuacin.
public class EntidadRSS { public string Titulo { get; set; } public string Descripcion { get; set; } public string Link { get; set; } }

Figura 5. Las fuentes RSS cargadas en la grilla.

Enviar informacin
As como hemos podido obtener informacin desde una fuente de datos remota, es posible enviar informacin hacia la fuente y esperar una respuesta basada en esto. Podemos hacer uso del mismo modelo antes planteado, pero adicionndole parmetros
233

7. INTERCONEXIN

que se incluirn en el envo de la informacin. Esta informacin podr ser manejada por el destino, se analizar y, segn ella, se generar una salida para visualizar en la aplicacin Silverlight. Como primer paso, crearemos una aplicacin Silverlight que incluya por defecto un sitio web de prueba (para recordar cmo hacerlo, podemos ver otra vez el captulo 3). Crearemos un nuevo sitio web junto con la aplicacin Silverlight para facilitarnos las pruebas de este ejemplo. Una vez creado el proyecto, tendremos que ver una estructura similar a la planteada en la siguiente figura.

Figura 6. Aplicacin Silverlight y sitio web en la misma solucin de proyecto.

Utilizaremos el sitio web existente para que acte como recolector de mensajes, el que leer la informacin enviada por la aplicacin Silverlight y devolver una respuesta para mostrar en ella. Implementaremos HttpHandler (manejadores web) para que representen nuestros puntos de entrada de datos. Para lograr esto, dentro del archivo Web.Config del sitio web, tendremos que agregar el manejador en cuestin. Junto con los manejadores creados por defecto, adicionaremos el nuestro.
<httpHandlers> <remove verb=* path=*.asmx/> <add verb=* path=capturaDeInformacion.aspx type=Capitulo7Posting.Web.ManejadorHTTP, Capitulo7Posting.Web/> <add verb=* path=*.asmx validate=false type=System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35/> <add verb=* path=*_AppService.axd validate=false

234

Silverlight desde C#

type=System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35/> <add verb=GET,HEAD path=ScriptResource.axd type=System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35 validate=false/> </httpHandlers>

En el HttpHandler declarado, ste tomar todas las peticiones que se realicen dentro de nuestro sitio web bajo el nombre de capturaDeInformacion.aspx. Todas las peticiones que se realicen bajo este nombre sern redirigidas a la clase ManejadorHTTP, por lo que deberemos adicionar esta clase y su cdigo respectivo a nuestra aplicacin web.
public class ManejadorHTTP : IHttpHandler { public bool IsReusable { get { return true; } } public void ProcessRequest(HttpContext context) { context.Response.ContentType = text/xaml; context.Response.Write(<Canvas xmlns=http://schemas.microsoft.com/client/2007 + xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml> +

RRR

HTTPHANDLER

Un HttpHandler nos otorga la posibilidad de capturar entradas HTTP a nuestro sitio web bajo un nombre especfico, sin tener que contar necesariamente con la pgina web fsica. Para poder usar HttpHandler, es necesario especificar el nombre de la clase que manejar la peticin, as como el espacio de nombre que la contiene.

235

7. INTERCONEXIN

<TextBlock Foreground=black Padding=10 FontSize=20>Hola + context.Request.QueryString[Texto] + </TextBlock></Canvas>); } }

Como vemos en el cdigo anterior, la clase ManejadorHTTP implementa la interfaz IHttpHandler, definindola como un manejador HTTP. Esta interfaz implementa dos mtodos, teniendo como importante el llamado ProcessRequest. Este mtodo presenta un comportamiento similar al de un evento y se disparar cada vez que se haga una peticin web que sea capturada por el manejador HTTP definido con anterioridad. En el objeto context, podremos encontrar toda la informacin referente a la peticin HTTP, incluso los valores enviados por el cliente. Al mismo tiempo, todo resultado que escribamos dentro del objeto context ser enviado de vuelta al cliente, por lo que podremos crear cualquier tipo de contenido y enviarlo de manera directa a nuestra aplicacin Silverlight. Como vemos en las dos lneas de cdigo de este mtodo, la primera redefine el tipo de salida, especificando que sta ser del tipo texto plano y con formato XAML. La siguiente lnea crea el texto de un control Canvas que contiene un control TextBlock que muestra un mensaje. Este mensaje incluye una palabra, ms lo enviado por el usuario. De esta forma, terminamos de definir el punto de contacto de nuestra aplicacin Silverlight y un servicio o recolector de mensajes distante. Del lado de Silverlight, lo primero que hacemos es crear el cdigo XAML para contener esta informacin y para darle la posibilidad al usuario de enviarla. Vemoslo a continuacin:
<UserControl x:Class=Capitulo7Posting.Page xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml Width=400 Height=300 xmlns:d=http://schemas.microsoft.com/expression/blend/2008 xmlns:mc=http://schemas.openxmlformats.org/markup-compatibility/2006 mc:Ignorable=d> <Grid x:Name=LayoutRoot Background=White> <Grid.RowDefinitions> <RowDefinition Height=0.16*/> <RowDefinition Height=0.84*/> </Grid.RowDefinitions>

236

Silverlight desde C#

<Grid.ColumnDefinitions> <ColumnDefinition/> </Grid.ColumnDefinitions> <TextBox Margin=57,8,0,18 Text= TextWrapping=Wrap Width=143 HorizontalAlignment=Left x:Name=textBox/> <Button Click=Button_Click HorizontalAlignment=Right Margin=0,8,153,18 Content=Enviar d:LayoutOverrides=Width, Height/> <TextBlock HorizontalAlignment=Left Margin=8,14,0,18 Text=Mensaje: TextWrapping=Wrap d:LayoutOverrides=Height/> <StackPanel x:Name=contenedor Margin=8,8,8,8 Grid.Row=1/> </Grid> </UserControl>

Figura 7. Aplicacin Silverlight que consumir un elemento distante.

Si bien ya hemos visto este cdigo en diferentes ocasiones, debemos destacar la presencia del control StackPanel al final del cdigo XAML. En este control, aplicaremos la respuesta del elemento HttpHandler ya creado. Por ltimo, creamos el cdigo que manejar la peticin y crear el control Silverlight basado en su cdigo XAML.
private void Button_Click(object sender, RoutedEventArgs e) { WebClient conectorWeb = new WebClient();

237

7. INTERCONEXIN

Uri direccionRSS = new Uri(http://localhost:1870/capturaDeInformacion.aspx?Texto= + this.textBox.Text); conectorWeb.Encoding = Encoding.UTF8; conectorWeb.DownloadStringCompleted += new DownloadStringCompletedEventHandler(conectorWeb_DownloadStringCompleted); conectorWeb.DownloadStringAsync(direccionRSS); } void conectorWeb_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { Canvas control = XamlReader.Load(e.Result.ToString()) as Canvas; this.contenedor.Children.Add(control); }

En el cdigo anterior, vemos cmo el valor de la caja de texto es pasada en la ruta de navegacin creada por el objeto Uri.
Uri direccionRSS = new Uri(http://localhost:1870/capturaDeInformacion.aspx?Texto= + this.textBox.Text);

Esto garantizar que el HttpHandler pueda leer el valor introducido por el usuario y actuar en consecuencia. En el cdigo, aparece un nuevo objeto que todava no habamos visto. Este objeto XamlReader permite crear controles Silverlight a partir del texto representativo en XAML. Este control carga el texto devuelto por el HttpHandler y crea una nueva instancia del control en cuestin. Finalmente, adicionamos este resultado a la lista de controles hijo del StackPanel.

RRR

SEGURIDAD SOBRE PARMETROS

Cuando usamos las entradas del usuario como parmetros en nuestras aplicaciones, deberemos tener sumo cuidado. Las entradas de los usuarios siempre deben ser comprobadas para que no contengan caracteres o cdigo ejecutable que pueda generar comportamientos no deseados. Cross Site Scripting o SQL Injection son dos de las vulnerabilidades ms comunes.

238

Almacenamiento aislado

Figura 8. El resultado devuelto por el HttpHandler y el nuevo control creado incluido dentro del StackPanel.

Como hemos podido comprobar, Silverlight puede salir fuera de su contenedor para comunicarse con otras aplicaciones conectadas a la red. Si bien slo hemos consumido informacin de pginas web, es posible hacerlo de servicios web, as como de la nueva plataforma de comunicacin de Microsoft, WCF (Windows Communication Foundation). Veremos estas alternativas, ms adelante, en este mismo captulo.

ALMACENAMIENTO AISLADO
Silverlight posee un mecanismo para poder guardar informacin de manera local en el cliente que est ejecutando la aplicacin. Si tenemos experiencia en el desarrollo web, podramos asociar la idea de este almacenamiento al utilizado por las cookies, elementos que son almacenados y administrados por el navegador del cliente, usados por lo general para dejar alguna informacin en ese equipo y que sern consultadas en posteriores ocasiones. Pero si bien conceptualmente resulta algo similar, el almacenamiento aislado en Silverlight presenta otras caractersticas. Pensemos en esta funcionalidad como en la posibilidad de tener una parte del disco duro de la mquina cliente para almacenar de manera segura informacin desde nuestra aplicacin Silverlight. Podramos, por ejemplo, cargar archivos desde el cliente, almacenarlos en este espacio reservado y usarlos luego en nuestra aplicacin. De esta manera, le ahorramos al usuario el tiempo de carga y evitamos pedirle que haga el mismo trabajo todas las veces que use la aplicacin. Por otro lado, esta caracterstica trae consigo un concepto de seguridad. Tengamos en cuenta que los navegadores web restringen el
239

7. INTERCONEXIN

acceso a archivos en el equipo del usuario. De esta forma, se aseguran de que diferentes aplicaciones y sitios web no puedan causar dao alguno al sistema operativo del usuario. Debido a este impedimento, y para no romper esta condicin, Silverlight nos permite crear y leer informacin desde el equipo del usuario de manera contenida, sin poder acceder ms all del espacio reservado para la aplicacin.

Implementar el almacenamiento aislado


Para poder usar almacenamiento aislado es necesario incluir el espacio de nombres System.IO.IsolatedStorage en nuestro cdigo. Una vez que lo hemos adicionado, podremos acceder de manera ms fcil a los objetos que administran esta funcionalidad. Debido a que Silverlight es el que nos proveer y administrar el espacio reservado para nuestra aplicacin, deberemos recuperar este espacio antes de poder leer o escribir cualquier informacin en l. Este espacio de nombre tiene tres elementos bsicos: IsolatedStorageFile: representa el almacn donde se encuentran todos los archivos correspondientes a la aplicacin y al usuario. Incluye archivos y directorios. IsolatedStorageFileStream: es utilizado para leer o escribir los distintos archivos dentro del almacn de datos. IsolatedStorageSettings: es un diccionario de datos representado por un par llave/ valor, que va a ser almacenado en el almacn de datos. Obtener el espacio designado para nuestra aplicacin es simple. Podemos hacerlo de la manera que vemos a continuacin:
IsolatedStorageFile almacen = IsolatedStorageFile.GetUserStoreForApplication();

Esto retornar una referencia al directorio y al espacio designado para nuestra aplicacin. Una vez que tenemos esta referencia, todo lo que leamos o escribamos pasar por este espacio reservado. Si tenemos experiencia en el manejo de archivos bajo Microsoft .Net, notaremos que el manejo del espacio reservado en Silverlight posee algunos puntos de contacto con su superior, teniendo diferentes mtodos para crear, borrar y leer archivos, as como para crear o borrar directorios. Los siguientes son los mtodos que tenemos a nuestra disposicin para trabajar con el almacn aislado: CreateDirectory: crea un nuevo directorio dentro del almacn. Podremos especificar un nombre para el directorio. DeleteDirectory: borra un directorio del almacn. CreateFile: crea un nuevo archivo, retornando un objeto IsolatedStorageFileStream.
240

Almacenamiento aislado

DeleteFile: elimina un archivo del almacn. Remove: se encarga de eliminar por completo el almacn junto con todos sus directorios y archivos contenidos. OpenFile: este mtodo abre un archivo guardado en el almacn y retorna un objeto IsolatedStorageFileStream. FileExists: verifica la existencia de un archivo en particular. Es til en casos en los que necesitemos saber si un archivo determinado ya fue creado o no. DirectoryExists: verifica la existencia de un directorio en particular. GetFileNames: devuelve un vector con los nombres de los archivos existentes en el almacn o en un directorio especfico de ste. GetDirectoryNames: este mtodo retorna un vector que contiene los nombres de los directorios dentro del almacn. Para poder crear un nuevo archivo dentro del almacn, escribiremos lo siguiente:
IsolatedStorageFile almacen; public Page() { InitializeComponent(); almacen = IsolatedStorageFile.GetUserStoreForApplication(); } private void Button_Click(object sender, RoutedEventArgs e) { using (IsolatedStorageFileStream archivo = almacen.CreateFile(archivo.txt)) { StreamWriter streamWriter = new StreamWriter(archivo); streamWriter.Write(DateTime.Now); streamWriter.Close(); } this.mensaje.Text = Se escribi un archivo.; }

Como vemos, para este caso se inicializa el almacn y el evento que disparar el botn. Usaremos este almacn para crear un archivo llamado archivo.txt, escribiendo en l la fecha actual. En la Figura 9, ubicada en la pgina siguiente, podemos observar el resultado obtenido con lo que hemos realizado.
241

7. INTERCONEXIN

Figura 9. El archivo fue creado con xito y se enva un mensaje al usuario para informarlo de este hecho.

As como hemos podido crear un nuevo archivo y guardar informacin en l, tambin tenemos la posibilidad de recuperar esa informacin y manipularla. Podremos hacer esto con el siguiente cdigo:
private void Button_Click_1(object sender, RoutedEventArgs e) { string contenido = string.Empty; using (IsolatedStorageFileStream archivo = almacen.OpenFile(archivo.txt,FileMode.OpenOrCreate)) { StreamReader streamReader = new StreamReader(archivo); contenido = streamReader.ReadToEnd(); streamReader.Close();

CIERRE DE ARCHIVOS

Es importante usar el mtodo Close() despus de cada operacin con archivos para marcar el fin de su uso y as liberarlo. Si no lo hiciramos, el archivo podra quedar tomado por la aplicacin y, al tratar de accederlo nuevamente, obtendramos un error ya que el archivo est en uso.

242

Almacenamiento aislado

} this.mensaje.Text = Un archivo ledo. Contenido: + contenido; }

En este caso, el contenido del archivo es recuperado y almacenado en una variable temporal para luego mostrar su valor en un mensaje, como vemos en la siguiente figura.

Figura 10. El archivo fue ledo y su contenido mostrado.

Notemos que, una vez que abrimos el archivo para leerlo, podemos especificar su modo de apertura mediante la enumeracin FileMode. Esta enumeracin posee algunas caractersticas especiales: CreateNew: especifica que se crear un nuevo archivo si no existiera anteriormente. Create: especifica que se crear un nuevo archivo. Si el archivo ya existe, entonces ste ser sobrescrito, y se perdern los datos del anterior. Open: abrir un archivo existente. Si el archivo no existe, ser arrojado un error. OpenOrCreate: abrir o crear un archivo basado en su existencia. Si el archivo existe, lo abrir. Si no, crear uno nuevo. Append: abre un archivo existente. Al hacerlo, desplazar el punto de lectura hacia el fin del archivo. De esta forma, lo que escribamos en l se har al final, y adicionar elementos al archivo existente. Ya hemos creado y ledo el archivo. Pero como dijimos, es posible hacer con l todas las operaciones bsicas con archivos. En este caso, borraremos el archivo escribiendo el cdigo que aparece en la prxima pgina:
243

7. INTERCONEXIN

private void Button_Click_2(object sender, RoutedEventArgs e) { almacen.DeleteFile(archivo.txt); this.mensaje.Text = Se elimin el archivo.; }

Figura 11. El archivo fue eliminado del almacn.

Todos los archivos son almacenados en una ubicacin especfica dentro del sistema operativo. En este caso, se ubican en las carpetas que contienen informacin del usuario.

Figura 12. Ubicacin del archivo creado en el almacn.


244

Almacenamiento aislado

Capacidad de almacenamiento
Por defecto, el espacio disponible para el almacenaje de datos es de 1 megabyte. Por supuesto, es posible que en determinadas circunstancias necesitemos ms espacio. Debido a que, como comentamos antes, Silverlight respeta el modelo de seguridad propuesto para el desarrollo web, no podremos aumentar la cantidad de espacio sin la autorizacin previa por parte del usuario. Pensemos que, de poder pasar por alto este tipo de validaciones, estaramos en condiciones de vulnerar la seguridad del usuario. Imaginemos que colmamos el total del espacio del disco duro del cliente sin que ste se entere. Definitivamente sera un problema y, por tal motivo, el usuario debe estar al tanto de esa accin antes de que nosotros podamos utilizar ms del espacio que es provisto por defecto. Es posible verificar e incrementar la cantidad de espacio disponible escribiendo el siguiente cdigo:
private void Button_Click_3(object sender, RoutedEventArgs e) { if (almacen.AvailableFreeSpace < 2000 * 1024) { if (almacen.IncreaseQuotaTo( almacen.Quota + (2000 * 1024) - almacen.AvailableFreeSpace)) { this.mensaje.Text = El espacio disponible es ahora de + (almacen.Quota + (2000 * 1024)).ToString() + ms.; } else { this.mensaje.Text = Usted no acept el incremento de tamao.; } } }

RRR

TAMAO DEL ALMACN

Es necesario verificar el tamao del almacn antes de hacer la peticin de incremento. Si la cuota actual fuera del mismo tamao o superior a la que estamos pidiendo, obtendrmos un error con la advertencia de que la cuota existente es igual o superior a la que reclamamos.

245

7. INTERCONEXIN

El cdigo anterior intentar pedir 2 megabytes adicionales a los ya usados. Si bien an no hemos usado nada del primer megabyte del espacio por defecto, este cdigo intentar incrementar en 2 megabytes ese espacio. Al ejecutar el cdigo, podemos ver la ventana emergente que nos pide autorizacin para incrementar el espacio disponible, como se muestra en la figura siguiente.

Figura 13. Peticin para incremento de la cuota en el almacn.

Si necesitamos conocer cunto espacio utiliza la aplicacin Silverlight, es posible acceder a esta informacin presionando el botn derecho del mouse y seleccionando la opcin Silverlight en el men desplegable. Al hacerlo, veremos todas las propiedades de la aplicacin en ejecucin. En la ltima pestaa, aparecern las propiedades relacionadas con el almacenamiento aislado, donde es posible saber el espacio consumido actualmente y hasta cunto podra crecer, adems de poder liberar este espacio con las opciones de esta ventana.

Figura 14. Opciones de la aplicacin Silverlight donde es posible ver el espacio de almacenamiento consumido y el disponible.
246

Almacenamiento aislado

Almacenar configuraciones
Es posible que necesitemos almacenar valores como textos u objetos complejos, pero sin la necesidad de tener que crear un archivo por nuestra cuenta. Podramos, por ejemplo, guardar la lista de productos de un carrito de compras o el nombre del usuario que est usando la aplicacin, pero sin llegar a tener que generar cdigo para manipular archivos almacenados de forma fsica. La caracterstica de almacenamiento aislado nos permite, adems de la manipulacin de archivos, la posibilidad de almacenar tipos de datos de manera simple y rpida, que se pueda recuperar en cualquier momento de la misma forma en la que fueron almacenados. Esto quiere decir que, si guardramos un objeto personalizado, recuperaramos el mismo objeto. Crearemos dos botones y una caja de texto para permitir al usuario introducir texto, que luego guardaremos y recuperaremos utilizando este mecanismo.
<TextBox VerticalAlignment=Bottom Text= TextWrapping=Wrap Margin=121,0,117,72 Height=25 x:Name=aplicacion/> <TextBlock HorizontalAlignment=Left VerticalAlignment=Bottom Text=Valor de aplicacin: TextWrapping=Wrap d:LayoutOverrides=Height Margin=8,0,0,76/> <Button Click=Button_Click_4 HorizontalAlignment=Left VerticalAlignment=Bottom Content=Almacenar d:LayoutOverrides=Width Margin=8,0,0,29/> <Button Click=Button_Click_5 HorizontalAlignment=Left VerticalAlignment=Bottom Content=Recuperar Margin=76,0,0,29/>

Como siguiente paso, tomaremos el valor de la caja de texto y la asignaremos a una variable de configuracin dentro del almacn.
private void Button_Click_4(object sender, RoutedEventArgs e) { IsolatedStorageSettings.ApplicationSettings[Texto] =

RRR

EL ALCANCE DEL ALMACENAMIENTO AISLADO

El almacenamiento aislado tiene un comportamiento diferente al de las cookies. ste no se maneja por navegador, sino por usuario. Esto quiere decir que acceder a la misma aplicacin con diferentes navegadores utilizar el mismo espacio reservado, sin importar quin cre inicialmente este espacio de almacenamiento.

247

7. INTERCONEXIN

this.aplicacion.Text; this.aplicacion.Text = ; }

Esta variable no necesita existir previamente y ser creada en el momento en el que sea asignada por primera vez. Si la variable ya existiera, su contenido ser remplazado con el nuevo valor. En el ejemplo anterior, el nombre de la variable es Texto y contendr el valor introducido por el usuario. A continuacin, podremos recuperar este valor con el siguiente cdigo:
private void Button_Click_5(object sender, RoutedEventArgs e) { this.aplicacion.Text = IsolatedStorageSettings.ApplicationSettings[Texto].ToString(); }

retornar un tipo de datos Object, por lo que es necesario transformarlo al tipo conocido, en este caso un String, para poder reasignarlo a la caja de texto. Como podemos ver en la figura que aparece debajo, los resultados almacenados desde un navegador son visibles en el otro.
ApplicationSettings

Figura 15. La variable almacenada por el usuario en el navegador de la izquierda, es leda desde la aplicacin Silverlight en el navegador de la derecha.

Como dijimos, es posible almacenar cualquier objeto o lista de stos dentro de estas variables de configuracin. De cualquier manera, es necesario que tengamos en cuenta que slo podrn ser almacenados aquellos elementos que contengan la cualidad de ser serializados. Esto quiere decir que podremos almacenar elementos,
248

Almacenamiento aislado

cuyos tipos de datos puedan ser transformados a XML. Para ilustrar esta posibilidad, crearemos una coleccin de entidades, alojndolas primero en una variable de configuracin que luego recuperaremos para llenar un control DataGrid.
<UserControl xmlns:data=clrnamespace:System.Windows.Controls;assembly=System.Windows.Controls.Data x:Class=Capitulo7AlmacenamientoObjetos.Page xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml Width=400 Height=300 xmlns:d=http://schemas.microsoft.com/expression/blend/2008 xmlns:mc=http://schemas.openxmlformats.org/markup-compatibility/2006 mc:Ignorable=d> <Grid x:Name=LayoutRoot Background=White> <Button HorizontalAlignment=Left Margin=8,8,0,0 VerticalAlignment=Top Content=Cargar lista/> <Button HorizontalAlignment=Left Margin=82,8,0,0 VerticalAlignment=Top Content=Mostrar lista d:LayoutOverrides=HorizontalAlignment/> <data:DataGrid Margin=0,51,0,0 x:Name=grillaDeDatos></data:DataGrid> </Grid> </UserControl>

El siguiente paso es crear una clase que contenga nuestra entidad y sirva para almacenar datos (podemos ver un ejemplo de esto en los captulos 3 y 4). En el momento en el que se ejecute el evento Click del botn, cargaremos una lista de nuestras entidades y las almacenaremos en una variable de configuracin.
private void Button_Click(object sender, RoutedEventArgs e) { List<Productos> productos = new List<Productos>(); productos.Add(new Productos() { Producto = Producto 1, Cantidad = 10, Categoria = Categoria 1, Precio = 100 });

249

7. INTERCONEXIN

productos.Add(new Productos() { Producto = Producto 2, Cantidad = 20, Categoria = Categoria 1, Precio = 50 }); //Agregar tantas como sean necesarias. IsolatedStorageSettings.ApplicationSettings[ListaProductos] = productos; }

Como podemos ver, se agrega la lista de productos sin realizarle ninguna modificacin. Esto se debe a que todos los elementos internos de la entidad pueden ser transformados a XML sin problema alguno. Finalmente, en el evento del segundo botn, leemos estos valores y los asignamos al control DataGrid. Para eso, el cdigo es el que aparece a continuacin:
private void Button_Click_1(object sender, RoutedEventArgs e) { this.grillaDeDatos.ItemsSource = IsolatedStorageSettings.ApplicationSettings[ListaProductos] as List<Productos>; }

Notemos que utilizamos la palabra reservada AS para transformar el resultado de la variable de configuracin al tipo conocido, o sea, una lista genrica de nuestra entidad. El resultado de estas dos acciones las podemos ver en la Figura 16.

RRR

SERIALIZACIN

Serializar informacin no es una tarea trivial. Podemos encontrarnos atascados fcilmente al momento de querer transformar nuestros objetos en distintos formatos de almacenamiento. Al aplicar este mecanismo, tambin podremos realizar acciones con la informacin. En http://msdn.microsoft.com/es-es encontraremos ms informacin.

250

Almacenamiento aislado

Figura 16. DataGrid cargado con datos tomados desde una variable de configuracin.

OpenFileDialog
es un control homnimo del usado en aplicaciones de escritorio. Permite abrir una ventana donde el usuario deber seleccionar un archivo de su equipo, archivo que podremos leer y manipular. Encontramos este tipo de comportamiento en pginas web en las que podemos seleccionar un archivo, como fotografas, para alojarlas en un servidor. El cdigo para crear un objeto del tipo OpenFileDialog es:
OpenFileDialog
OpenFileDialog ventanaDialogo = new OpenFileDialog();

Para abrir la ventana de seleccin, deberemos llamar al mtodo ShowDialog(). Este mtodo retornar el valor True cuando el usuario aplique los archivos seleccionados.
OpenFileDialog ventanaDialogo = new OpenFileDialog(); ventanaDialogo.Filter = Archivos de texto (*.txt)|*.txt; ventanaDialogo.Multiselect = true; if (ventanaDialogo.ShowDialog() == true) { ...

En el cdigo anterior, tambin podemos notar que es posible definir el filtro de los archivos por buscar, as como si se permitir seleccionar ms de un archivo al
251

7. INTERCONEXIN

mismo tiempo. El ejemplo que vemos a continuacin muestra todos los archivos cargados por el usuario en un control ListBox.
private void Button_Click(object sender, RoutedEventArgs e) { OpenFileDialog ventanaDialogo = new OpenFileDialog(); ventanaDialogo.Filter = Archivos de texto (*.txt)|*.txt; ventanaDialogo.Multiselect = true; if (ventanaDialogo.ShowDialog() == true) { List<string> listaArchivos = new List<string>(); foreach (FileInfo archivo in ventanaDialogo.Files) { listaArchivos.Add(archivo.Name); } this.listaDeArchivos.ItemsSource = listaArchivos; } }

Figura 17. El filtro mostrar slo archivos con extensin TXT o de texto para seleccionar.

Luego de que el usuario selecciona los archivos permitidos por el filtro establecido, todos sus nombres son listados en el control ListBox, como podemos observar en la Figura 18, ubicada en la pgina siguiente.
252

Almacenamiento aislado

Figura 18. Lista de todos los archivos seleccionados por el usuario.

Podremos agregar tantos filtros como creamos necesarios. Para lograr esto, modificaremos el filtro inicial incluyendo otros, de la siguiente manera:
ventanaDialogo.Filter = Archivos de texto (*.txt)|*.txt|Imgenes JPG (*.jpg)|*.jpg;

Ahora, tenemos un nuevo tipo disponible para seleccionar en el cuadro de dilogo:

Figura 19. Un nuevo filtro agregado a la lista de elementos seleccionables.


253

7. INTERCONEXIN

Es posible combinar el uso del objeto OpenFileDialog con la funcionalidad de almacenamiento aislado. En el siguiente ejemplo, copiaremos los archivos seleccionados por el usuario a una seccin del almacn reservado para nuestra aplicacin.
IsolatedStorageFile almacen; public Page() { InitializeComponent(); almacen = IsolatedStorageFile.GetUserStoreForApplication(); } private void Button_Click(object sender, RoutedEventArgs e) { OpenFileDialog ventanaDialogo = new OpenFileDialog(); ventanaDialogo.Filter = Archivos de texto (*.txt)|*.txt|Imgenes JPG (*.jpg)|*.jpg; ventanaDialogo.Multiselect = true; if (ventanaDialogo.ShowDialog() == true) { List<string> listaArchivos = new List<string>(); foreach (FileInfo archivo in ventanaDialogo.Files) { listaArchivos.Add(archivo.Name); using (Stream datosArchivo = archivo.OpenRead()) { using (IsolatedStorageFileStream datosAlmacen = almacen.CreateFile(archivo.Name)) { byte[] buffer = new byte[1024]; int count = 0; do { count = datosArchivo.Read(buffer, 0, buffer.Length); if (count > 0) datosAlmacen.Write(buffer, 0, count); } while (count > 0); }

254

Manejo de hilos

} } this.listaDeArchivos.ItemsSource = listaArchivos; } }

Por cada elemento ledo desde el dilogo de archivos, crearemos un nuevo archivo en el almacn con el mismo nombre, copiando sus datos de forma binaria. Como resultado, podremos ver que los archivos seleccionados previamente fueron copiados a la ruta del almacn.

MANEJO DE HILOS
Quizs, no estemos familiarizados con el manejo de hilos, tambin llamados threads por su nombre en ingls. Esta caracterstica es tpica de las aplicaciones de escritorio, donde es posible ejecutar ms de un proceso, funcin o pieza de cdigo de manera simultnea. Esto quiere decir que podremos tener ms de una pieza funcional de cdigo dentro de nuestra aplicacin, procesando informacin de manera paralela. Para entender esto an ms, pensemos en cdigo que podra tomar mucho tiempo en ejecutarse, como modificar una imagen, insertar registros en una base de datos de forma masiva o generar un clculo matemtico de alta complejidad. Estos procesos pueden tomar mucho tiempo en llevarse a cabo, y hacer esperar al usuario hasta que ese proceso finalice antes de que pueda seguir usando nuestra aplicacin, podra resultar poco prctico. De esta forma, estos procesos de alta complejidad podran ser ejecutados de manera paralela haciendo que, en el momento en el que terminen su ejecucin, nos avisen para que podamos continuar con otro tipo de tarea. Silverlight no est exento de esta capacidad, a pesar de tener una firma muy pequea y estar pensado para que sea liviano y rpido.

RRR

HILOS

Si bien el uso de hilos puede ser de gran ayuda para la ejecucin de tareas en paralelo, debemos tener en cuenta que ste no es un recurso inagotable y, por ms hilos que creemos y tareas que ejecutemos en paralelo, el rendimiento de nuestra aplicacin no ser constante. Es importante no abusar de estos elementos en nuestro cdigo.

255

7. INTERCONEXIN

El concepto de hilos
En los diferentes captulos ya hemos tenido algunos contactos con el manejo de hilos. Si bien no hemos creado ni declarado hilos de manera explcita, s hemos usado objetos que poseen un comportamiento similar. Objetos como Storyboard o Timer son algunos ejemplos de componentes que pueden ejecutar cdigo en un hilo de ejecucin distinto del primario definido por la aplicacin, disparando eventos basados en ciertos estmulos ya configurados. Esto es posible debido a que el sistema operativo es el que administra los procesos de cada aplicacin que se ejecuta, asignndole un espacio de tiempo para realizar sus tareas. As, el sistema operativo ir iterando entre cada uno de estos procesos, adems de sus propios procesos, y de esta forma permitir que las aplicaciones no tomen el control absoluto de todo el equipo. Es comn que el manejo de hilos pase desapercibido cuando usamos o desarrollamos cualquier aplicacin, pero pensemos que el hecho de que podamos mover el puntero del mouse y al, mismo tiempo, escuchar msica o escribir un documento es gracias a que el sistema operativo, a altsima velocidad, est otorgndole una fraccin de tiempo a cada una de estas aplicaciones para que puedan realizar sus trabajos. En el caso de las aplicaciones visuales, todo el manejo de la interfaz visual, as como de la lgica de esa aplicacin, se realiza en un nico hilo de ejecucin. Debido a esto, tener una tarea que capte todo el tiempo disponible otorgado por el sistema operativo para la ejecucin de procesos podra bloquear la interfaz visual, haciendo pensar que la aplicacin ha sufrido un problema y que no funcionar correctamente. Para ilustrar esto, veamos el siguiente cdigo:
public Page() { InitializeComponent(); ProcesoLargo(); } public void ProcesoLargo() { for (long i = long.MinValue; i <= long.MaxValue; i++) { } }

El cdigo anterior no es muy complejo, pero el bucle presentado itera entre valores bastante amplios bloqueando por completo el hilo principal de ejecucin de la aplicacin, lo que hace que no podamos interactuar con ella hasta que el bucle finalice
256

Manejo de hilos

por completo. Como resultado de la ejecucin del cdigo anterior, somos proclives a obtener errores como el que vemos en la siguiente figura.

Figura 20. La nica alternativa posible es terminar abruptamente la ejecucin de la aplicacin.

Para este tipo de tareas, entonces, lo recomendable sera crear un nuevo hilo de ejecucin para que estas lneas de cdigo se ejecuten en paralelo y as no bloquear toda la aplicacin. Conozcamos algunas formas de hacerlo.

Temporizador
Una de las primeras implementaciones provistas por Microsoft .Net Framework que implementan hilos son los temporizadores, tambin conocidos como Timers por su nombre en ingls. En el caso de Silverlight, tenemos un temporizador especial dentro del espacio de nombres System.Windows.Threading. Este temporizador es llamado DispatcherTimer y cumple la funcin de disparar un evento basado en un intervalo dado. DispatcherTimer posee las siguientes propiedades: Interval: el intervalo representa el tiempo en milisegundos que deber transcurrir antes de disparar el evento Tick. Start: inicia el temporizador. Una vez configurado el objeto DispatcherTimer, debemos llamar al mtodo Start() para iniciar la ejecucin del temporizador. Stop: detiene la ejecucin del temporizador. Tick: ste es el evento al que deberemos subscribirnos para recibir las alertas disparadas por DispatcherTimer cada vez que transcurra el tiempo configurado en la propiedad Interval que vimos al principio de esta lista.
257

7. INTERCONEXIN

Podramos usar DispatcherTimer para generar una aplicacin tipo reloj, actualizando los minutos o segundos en tiempo real; o en otras implementaciones tales como el envo de informacin hacia un servicio o pgina web desde nuestra aplicacin Silverlight sin intervencin del usuario y, al mismo tiempo, sin bloquear el hilo principal de ejecucin de la aplicacin. En el siguiente ejemplo, vemos cmo aplicar este temporizador para actualizar el progreso de un control ProgressBar.
<UserControl x:Class=Capitulo7Hilos.Page xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml Width=400 Height=300> <Grid x:Name=LayoutRoot Background=White> <ProgressBar x:Name=progressBar VerticalAlignment=Top Height=24 Margin=23,39,26,0 /> </Grid> </UserControl>

Una vez que hemos definido el control ProgressBar, declaramos el temporizador DispatcherTimer y actualizamos el resto del control ProgressBar por cada Tick() ejecutado por el objeto temporizador.
DispatcherTimer temporizador; public Page() { InitializeComponent(); temporizador = new DispatcherTimer(); temporizador.Tick += new EventHandler(temporizador_Tick); temporizador.Interval = TimeSpan.FromSeconds(1); temporizador.Start(); } void temporizador_Tick(object sender, EventArgs e) { this.progressBar.Value++; }

Como vemos en la Figura 21 de la prxima pgina, el control ProgressBar es actualizado dentro del rango de tiempo fijado por el control DispatcherTimer.
258

Manejo de hilos

Figura 21. En cada navegador, vemos los diferentes estados del control ProgressBar, actualizado cada un segundo de ejecucin.

Personalizar los hilos


En el caso anterior, donde vimos el objeto DispatcherTimer, ste fue creado para realizar una tarea especfica: generar su propio proceso o hilo de ejecucin y avisarnos cada vez que el tiempo configurado fuera alcanzado. Este comportamiento no nos resultar para nada prctico en casos ms especficos o avanzados. Supongamos que necesitamos modificar el comportamiento del control ProgressBar sobre la base del progreso real de una tarea que es ejecutada por una funcin creada por nosotros. Para estos casos, es posible colocar la ejecucin de esa funcin o mtodo en un hilo separado. Esto, como ya dijimos, har que el hilo principal, aquel que administra la interfaz del usuario, no se bloquee, dndole al usuario una experiencia ms agradable al ejecutar la aplicacin.
private void RealizarProceso() { for (int i = 0; i < 100; i++) { this.progressBar.Value = (double)valor; Thread.Sleep(500); } }

En el caso anterior, si ejecutramos el proceso en forma directa, conseguiramos que la interfaz visual quedara completamente bloqueada, en especial por la lnea:
Thread.Sleep(500);

259

7. INTERCONEXIN

Esta lnea detendr el hilo de ejecucin actual durante medio segundo, por lo que, por cada iteracin del bucle, todo el hilo de ejecucin se detendr. Para este caso, escribimos esa lnea slo para lograr una sensacin de trabajo por parte de la aplicacin y no cargar en forma instantnea la barra de progreso. En todo caso, el problema persiste ya que seguiremos bloqueando el hilo principal de ejecucin, a menos que ejecutemos esta funcin en un hilo diferente, como vemos en el siguiente cdigo:
private void Button_Click(object sender, RoutedEventArgs e) { ThreadStart referenciaProceso = new ThreadStart(RealizarProceso); Thread nuevoHilo = new Thread(referenciaProceso); nuevoHilo.Start(); }

Como primer paso, creamos un delegado del tipo ThreadStart, el cual recibe como parmetro el nombre de la funcin o mtodo que queramos ejecutar de manera asncrona. El siguiente paso consiste en crear un nuevo hilo de ejecucin mediante el uso de la clase Thread y asignarle al parmetro requerido el delegado creado previamente. Hasta este punto, slo hemos creado el ambiente de ejecucin del nuevo hilo, por lo que usaremos el mtodo Start() para iniciar el proceso. Si ejecutamos el nuevo proceso tal como lo hemos escrito, veremos que obtendremos un error en la ejecucin. Esto se debe a que no es posible, en Silverlight, modificar elementos de manera directa entre diferentes procesos. Pensemos que la interfaz visual se est ejecutando en un hilo, como ya hemos podido comprobar, y la funcin, ahora, se ejecuta en otro hilo, por lo que estos dos hilos de ejecucin no pueden alterarse entre ellos. Para poder hacerlo, es necesario dejar que el manejador del hilo principal se encargue de hacer las actualizaciones correspondientes a los elementos que pertenezcan a su dominio o estn bajo l.
this.Dispatcher.BeginInvoke((ThreadStart)delegate() { this.progressBar.Value = (double)valor; } );

El cdigo le avisa, al manejador del hilo, que debe ejecutar la actualizacin de la barra de progreso. Para esto, utilizamos otro delegado para crear un mtodo annimo, el cual ejecutar la actualizacin del control cuando el hilo principal pueda procesarlo.
260

Manejo de hilos

Hilos y eventos
Podemos llegar an ms lejos con Silverlight y el uso de hilos de ejecucin si implementamos eventos. Si bien ya estamos familiarizados con los eventos debido a que hemos hecho uso de ellos con la implementacin de botones, listas desplegables y otros controles con la capacidad de notificarnos el momento en que se produce un cambio interno en el control o cuando el usuario interacta con l, tambin es posible crear estos eventos por nuestra cuenta. Esto puede ser especialmente til si lo conjugamos con el uso de hilos. De esta forma, podramos iniciar un hilo de ejecucin para una tarea y hacer que sta, al finalizar o al suceder diferentes hitos, nos avise de estos hechos para que el cdigo que hubiera iniciado el nuevo proceso sepa cmo reaccionar basado en estos cambios. Podemos declarar un evento de la siguiente forma:
delegate void delegadoEvento(int valor); event delegadoEvento eventoHilo;

Notemos que la primera lnea es un delegado. Este delegado representa la firma que debern tener aquellas funciones o mtodos que quieran obtener alguna notificacin por parte del evento. En este caso, la funcin que implemente este evento deber recibir un valor entero como parmetro de entrada. La siguiente lnea es el evento propiamente dicho, el cual hace uso de la firma provista por el delegado creado con anterioridad. Si extendemos el ejemplo utilizado para crear nuestros propios hilos, podramos asociar la funcin de actualizacin de la barra de progreso al evento para que, cuando el hilo ejecutado en paralelo ejecute cada iteracin, nos notifique de los cambios realizados por medio del evento.
private delegate void delegadoEvento(int valor); private event delegadoEvento eventoHilo; public Page()

RRR

DELEGADOS

Si bien el concepto de delegados es mucho ms complejo y profundo, para entenderlo de manera rpida podemos decir que un delegado es el equivalente a un puntero o apuntador hacia una funcin o mtodo. Este delegado es usado, en la mayora de los casos, para llamar a la funcin apuntada desde otros mtodos y procesos.

261

7. INTERCONEXIN

{ InitializeComponent(); eventoHilo += new delegadoEvento(Page_eventoHilo); } void Page_eventoHilo(int valor) { this.Dispatcher.BeginInvoke((ThreadStart)delegate() { this.progressBar.Value = (double)valor; } ); }

Veamos que concatenamos al evento un delegado que apunta a una funcin creada por nosotros y que contiene la actualizacin de la barra de progreso. Por ltimo, la funcin que incluye la iteracin es modificada para que dispare este evento.
private void RealizarProceso() { for (int i = 0; i < 100; i++) { eventoHilo(i); Thread.Sleep(500); } }

Los eventos suelen ser una gran ayuda en implementaciones complejas. De cualquier manera, es necesario tener cuidado cuando trabajemos con eventos, ya que pueden arrojarnos un error si ninguna funcin o mtodo se suscribi. Esto quiere decir que, mientras nadie se suscriba al evento, ste ser nulo y, cuando intentemos ejecutarlo, obtendremos un error de referencia no inicializada. Para solucionar este problema, es recomendable usar el cdigo que aparece debajo. As, podremos garantizar que si nadie se ha suscrito al evento, ste no se disparar y, por ende, no obtendremos un error.
if (eventoHilo != null) { eventoHilo(i); }

262

Consumir servicios desde Silverlight

Figura 22. Si no se asocia ninguna funcin al evento, ste genera un error al intentar ejecutarse.

CONSUMIR SERVICIOS DESDE SILVERLIGHT


Al principio de este captulo hicimos uso del objeto WebClient para enviar informacin haca una pgina web y tomar los resultados arrojados por ella. Pudimos crear un lector de RSS y tambin capturar datos desde la pgina sobre la base de los datos introducidos por el usuario en nuestra aplicacin Silverlight. Si bien ste puede ser un buen mecanismo para enviar e interactuar con elementos que se encuentren fuera de nuestra aplicacin web, no sirve para cubrir todos los casos posibles. Pensemos en modelos donde necesitemos agregar mayor seguridad al transporte de la informacin o en el que requiramos poder obtener informacin en forma de tipos de datos concretos y conocidos por nuestra aplicacin. Para estos casos, es comn la implementacin de servicios web en los que un sitio, nuestro o de un tercero, expone en Internet mtodos o funciones para procesar y devolver informacin. Otras aplicaciones pueden conectarse a estos servicios, consumir esa informacin y mostrarla en el mbito de la misma aplicacin, simulando que los datos desplegados fueran generados por sta, sin tener que enviar al usuario a una pgina web distante. As como podemos conectarnos a servicios distantes, tambin es posible consumir informacin de servicios creados por nosotros y que trabajen en nuestro sitios web. Para esto, necesitamos contar con un sitio web; y para ello crearemos una aplicacin Silverlight dejando que Visual Studio cree el sitio web utilizado para poder depurar y visualizar la aplicacin Silverlight. Una vez que tengamos
263

7. INTERCONEXIN

nuestra solucin creada, en el proyecto web adicionaremos un nuevo servicio web, como vemos en la figura que aparece a continuacin.

Figura 23. Debemos adicionar un nuevo servicio web a nuestra aplicacin ASP.net.

Si no hemos trabajado nunca con servicios web creados con Microsoft .Net, notaremos que no existe diferencia alguna con un mtodo o funcin tradicional del lenguaje que estemos acostumbrados a usar. De cualquier manera, este mtodo es decorado con algunos atributos que especifican su alcance, como podemos ver a continuacin:
[WebService(Namespace = http://tempuri.org/)] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] public class MiServicioWeb : System.Web.Services.WebService { [WebMethod] public long Sumar(long valor1, long valor2) { return valor1 + valor2; } }

El atributo decorativo [WebMethod] especifica que la funcin o mtodo dentro del servicio web resulta accesible desde Internet o la Web. De esta forma, el mtodo
264

Consumir servicios desde Silverlight

queda expuesto a las distintas aplicaciones que quieran consumirlo. Para poder consumir un servicio web, primero necesitaremos saber dnde se encuentra, en la Web, ese servicio. Sin esta ruta, no podremos acceder a l. En el caso del servicio web creado previamente, si estamos trabajando de manera local, es posible ver su direccin al ejecutar el servicio. Por lo general, podremos encontrarlo con el apartado http://localhost que hace referencia a nuestro equipo. El siguiente paso es el de adicionar esta referencia al servicio dentro de nuestra aplicacin Silverlight. Para esto, agregaremos una nueva referencia web apuntando al servicio en cuestin, como vemos en la siguiente figura.

Figura 24. Agregando una referencia de un servicio web a nuestra aplicacin Silverlight.

Entre los protocolos de comunicacin usados por los servicios web, se encuentra el llamado SOAP (Simple Object Access Protocol, o en castellano, protocolo de acceso a objetos simple). Este protocolo sirve para transportar objetos de forma simple entre aplicaciones. Adems, se basa en XML para representar los distintos elementos que se transportarn y, si bien no es el objetivo de este libro profundizar en este protocolo, s es necesario mencionar que, en el caso de Silverlight, usaremos SOAP para transportar la informacin entre nuestra aplicacin y el servicio web. Una vez

THREAD.SLEEP()

El uso de Thread.Sleep() en los ejemplos es slo para ilustrar un comportamiento de carga en la aplicacin. Ya que Thread.Sleep() detiene momentneamente la ejecucin del hilo actual, el uso en aplicaciones finales podra causar un deterioro en la velocidad de ejecucin de sta.

265

7. INTERCONEXIN

adicionada la referencia al servicio web, podremos verla en el rbol del proyecto. El servicio creado tiene la finalidad de sumar dos nmeros largos y retornarnos el resultado de la operacin. Para esto, es necesario que primero enviemos estos nmeros introducidos por el usuario. Crearemos una interfaz con un par de controles TextBox, un botn y algunas etiquetas para escribir en ellas.
<UserControl x:Class=Capitulo7ServiciosWeb.Page xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml Width=400 Height=300 xmlns:d=http://schemas.microsoft.com/expression/blend/2008 xmlns:mc=http://schemas.openxmlformats.org/markup-compatibility/2006 mc:Ignorable=d> <Grid x:Name=LayoutRoot Background=White> <Button Click=Button_Click Margin=167,30,190,0 VerticalAlignment=Top Content=Sumar d:LayoutOverrides=Width/> <TextBox HorizontalAlignment=Left Margin=8,28,0,0 VerticalAlignment=Top Width=69 Text= TextWrapping=Wrap x:Name=valor1/> <TextBox HorizontalAlignment=Left Margin=94,28,0,0 VerticalAlignment=Top Width=69 Text= TextWrapping=Wrap x:Name=valor2/> <TextBlock x:Name=resultado HorizontalAlignment=Left Margin=8,69,0,0 VerticalAlignment=Top Text=Resultado: TextWrapping=Wrap Width=155/> <TextBlock HorizontalAlignment=Left Margin=8,8,0,0 VerticalAlignment=Top Width=177 Text=Escriba los nmeros a sumar: TextWrapping=Wrap/> </Grid> </UserControl>

_`

EL CANAL DEL CLIMA

El canal del clima o Weather Channel, posee un servicio web para consulta del clima. Con este servicio, tendremos la capacidad de desplegar los datos climticos de cualquier parte del mundo en nuestra aplicacin. Podemos registrarnos a este servicio de forma gratuita por medio de su sitio web en www.weather.com/services/xmloap.html.

266

Consumir servicios desde Silverlight

El siguiente paso consiste en tomar los valores introducidos por el usuario, conectarse al servicio web y entregarle estos valores.
private void Button_Click(object sender, RoutedEventArgs e) { ServicioSumar.MiServicioWebSoapClient servicio = new ServicioSumar.MiServicioWebSoapClient(); servicio.SumarCompleted += new EventHandler<ServicioSumar.SumarCompletedEventArgs> (servicio_SumarCompleted); servicio.SumarAsync(long.Parse(this.valor1.Text), long.Parse(this.valor2.Text)); }

Como podemos ver, deberemos realizar tres pasos para poder trabajar con el servicio web. Primero, crearemos una instancia del servicio ya adicionado como referencia web a nuestro proyecto. Luego, enlazamos un mtodo o funcin al evento Completed del mtodo por ejecutar. Esto es debido a que necesitamos llamar de forma asncrona al servicio web, y este evento nos avisar cuando la llamada se haya completado. Por ltimo, ejecutamos el evento del servicio pasando los dos valores introducidos por el usuario. Una vez que el servicio haya realizado de manera correcta el proceso de suma, nos retornar el resultado para que podamos desplegarlo en nuestra aplicacin.
void servicio_SumarCompleted(object sender, ServicioSumar.SumarCompletedEventArgs e) { this.resultado.Text = Resultado: + e.Result.ToString(); }

RRR

PROBAR SERVICIOS WEB

Debido a que los datos transferidos por un servicio web son, tpicamente, XML, puede resultar difcil probar el servicio sin tener que realizar cdigo. Por esto, Microsoft .Net nos provee de una interfaz web para probar el servicio. Para acceder a ella, slo tendremos que navegar hasta el servicio de forma local.

267

7. INTERCONEXIN

El objeto e contiene los resultados devueltos por el servicio, por lo que tomamos de ste la respuesta enviada por el servicio llamado previamente.

Figura 25. Al llamar al servicio envindole los dos valores introducidos por el usuario, el servicio realiza el clculo matemtico y retorna el resultado.

Si bien en el ejemplo hemos enviado y recibido tipos de datos primitivos, es posible tambin enviar y recibir tipos complejos, como entidades de datos, listas y colecciones de elementos, entre otros. Para entender esto, crearemos en el proyecto que contiene el servicio web una entidad para transportar datos de un usuario de la siguiente forma:
public class Usuarios { public string Nombre { get; set; } public string Apellido { get; set; } public string Correo { get; set; } }

Esta clase representar los datos de un usuario que trataremos de enviar a la aplicacin Silverlight desde el servicio web. Para esto, tendremos que agregar un nuevo mtodo web que retorne dicha entidad, como vemos a continuacin:
268

Consumir servicios desde Silverlight

[WebMethod] public Usuarios LeerUsuario() { return new Usuarios() { Nombre = Usuario 1, Apellido = Apellido 1, Correo = Correo 1 }; }

De la misma forma que hicimos en el primer ejemplo, deberemos conectarnos al servicio web, llamar al mtodo que retorne el tipo complejo para luego poder manipularlo en la aplicacin Silverlight.
private void Button_Click_1(object sender, RoutedEventArgs e) { ServicioSumar.MiServicioWebSoapClient servicio = new ServicioSumar.MiServicioWebSoapClient(); servicio.LeerUsuarioCompleted += new EventHandler<ServicioSumar.LeerUsuarioCompletedEventArgs> (servicio_LeerUsuarioCompleted); servicio.LeerUsuarioAsync(); } void servicio_LeerUsuarioCompleted(object sender, ServicioSumar.LeerUsuarioCompletedEventArgs e) { List<ServicioSumar.Usuarios> usuarios = new List<ServicioSumar.Usuarios>(); usuarios.Add(e.Result); this.grilla.ItemsSource = usuarios; }

Como el servicio expone el tipo complejo al devolverlo en el mtodo LeerUsuario, este tipo puede ser usado desde la aplicacin Silverlight para reconocer el valor retornado y as capturar los resultados. En la Figura 26, vemos el resultado de llamar al servicio web, leer el resultado y asignarlo a una grilla de datos.
269

7. INTERCONEXIN

Figura 26. La grilla muestra el registro enviado por el servicio web.

Si hacemos uso de las ltimas tecnologas propuestas por Microsoft, vale mencionar que Silverlight no slo puede consumir informacin de servicios web clsicos, sino que tambin puede conectarse y consumir informacin de servicios WCF (Windows Communication Foundation). Esta tecnologa permite inicializar y hospedar servicios sin la necesidad de contar con un servidor que contenga IIS (Internet Information Services) para administrar el servicio, como pasara en el caso de los primeros servicios web creados en este captulo.

Crear un servicio WCF


El primer paso para crear nuestro servicio WCF ser agregar, al proyecto web creado junto con nuestra aplicacin Silverlight, un servicio del tipo WCF para Silverlight. Luego, debemos seleccionar el tipo de servicio. En este caso, un servicio WCF preparado para ser consumido desde Silverlight. Este servicio, a diferencia del que ya hemos usado, posee dos atributos nuevos para identificar el servicio y los mtodos expuestos: ServiceContract: este contrato de servicio, distingue la clase que ser expuesta como un servicio. Esta clase puede contener diferentes mtodos expuestos. OperationContract: los contratos de operacin representan cada uno de los mtodos o funciones expuestos por el servicio y con los cuales se podr interactuar.
[ServiceContract(Namespace = )] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

270

Consumir servicios desde Silverlight

public class ServicioWCF { [OperationContract] public void EscribirMensaje(string mensaje) { ... } }

La segunda parte hace referencia a la configuracin y exposicin del servicio. Esto se realiza dentro del archivo de configuracin de la aplicacin, por lo general, representado con el nombre App.Config o en un ambiente web como Web.Config.
<system.serviceModel> <behaviors> <serviceBehaviors> <behavior name=Capitulo7WCFService.Web.ServicioWCFBehavior> <serviceMetadata httpGetEnabled=true /> <serviceDebug includeExceptionDetailInFaults=false /> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment aspNetCompatibilityEnabled=true /> <services> <service behaviorConfiguration=Capitulo7WCFService.Web.ServicioWCFBehavior name=Capitulo7WCFService.Web.ServicioWCF> <endpoint address= binding=basicHttpBinding contract=Capitulo7WCFService.Web.ServicioWCF /> <endpoint address=mex binding=mexHttpBinding contract=IMetadataExchange /> </service> </services> </system.serviceModel>

Esta configuracin define por completo el comportamiento que tendr el servicio. Incluye informacin relacionada con el descubrimiento del servicio por otras aplicaciones y el detalle de las excepciones que ste arroja. Con el servicio configurado, slo nos resta crear la implementacin del contrato.
271

7. INTERCONEXIN

[ServiceContract(Namespace = )] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class ServicioWCF { [OperationContract] public void EscribirMensaje(string mensaje) { Debug.WriteLine(mensaje); return; } }

En este caso, todos los mensajes que reciba el servicio sern escritos en la consola de depuracin. De esta forma, comprobaremos que la conexin es exitosa y que los mensajes estn siendo recibidos por el servicio. Podremos verificar previamente que el servicio se encuentra activo, ejecutando la aplicacin web y accediendo a la ruta donde ese servicio se encuentra alojado, como podemos ver en la Figura 27.

Figura 27. El servicio WCF funciona de manera correcta.

De la misma forma en que adicionamos el servicio web a nuestra aplicacin Silverlight, el servicio WCF debe ser referenciado y adicionado a nuestra aplicacin, como podemos ver en la Figura 28. El procedimiento es idntico, y se puede seleccionar el servicio en cuestin sobre la base de la direccin donde est alojado.
272

Consumir servicios desde Silverlight

Figura 28. Adicionando el servicio WCF a la aplicacin Silverlight.

Una vez adicionado el servicio, notaremos que el archivo de configuracin de la aplicacin Silverlight ha sido modificado para especificar la forma en la que sta se conectar al servicio WCF. Esta configuracin resulta de igual importancia que la vista anteriormente, ya que ambas deben tener cierta concordancia para que tanto la aplicacin que consume el servicio como el servicio en s se comuniquen de igual forma. Veamos el cdigo necesario para esto:
<configuration> <system.serviceModel> <bindings> <basicHttpBinding> <binding name=BasicHttpBinding_ServicioWCF maxBufferSize=2147483647 maxReceivedMessageSize=2147483647> <security mode=None />

RRR

MTODOS ANNIMOS

Un mtodo annimo es una pieza de cdigo que no posee una firma (nombre de funcin) especfica. Todo el cdigo generado para este mtodo es apuntado por un delegado, el cual representar el punto de entrada para la ejecucin de las lneas creadas dentro de ese mtodo annimo.

273

7. INTERCONEXIN

</binding> </basicHttpBinding> </bindings> <client> <endpoint address=http://localhost:2113/ServicioWCF.svc binding=basicHttpBinding bindingConfiguration=BasicHttpBinding_ServicioWCF contract=ServicioWCF.ServicioWCF name=BasicHttpBinding_ServicioWCF /> </client> </system.serviceModel> </configuration>

Cuando ya tenemos todos los elementos configurados, slo nos resta llamar al servicio pasndole los parmetros definidos por ste. Notaremos que la forma de hacerlo es idntica a la que ya hemos usado.
private void Button_Click(object sender, RoutedEventArgs e) { ServicioWCF.ServicioWCFClient servicio = new ServicioWCF.ServicioWCFClient(); servicio.EscribirMensajeCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(servicio_ EscribirMensajeCompleted); servicio.EscribirMensajeAsync(this.textoMensaje.Text); } void servicio_EscribirMensajeCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) { }

Si ejecutamos nuestra aplicacin Silverlight, podremos ver con claridad cmo los valores escritos en sta son enviados al servicio para que, por ltimo, sean escritos en la consola de depuracin, como vemos en la siguiente imagen.
274

Manipular datos

Figura 29. Mientras se envan datos desde Silverlight, el servicio los escribe en la consola de depuracin.

De esta forma, hemos podido conectarnos tanto a servicios web tradicionales como al nuevo modelo de comunicacin de Microsoft: Windows Communication Foundation. El acceso y manipulacin de servicios puede sernos de extrema ayuda en los casos en que necesitemos extender la funcionalidad de Silverlight o interconectarlo con aplicaciones y lenguajes que no estn directamente relacionados a tecnologas Microsoft. Pensemos en la posibilidad de conectarnos a servicios creados en lenguajes, como PHP, Java o Ruby, que trabajen en ambientes no relacionados en forma directa con productos Microsoft, como Windows.

MANIPULAR DATOS
En el desarrollo de aplicaciones empresariales, uno de los puntos fuertes es la manipulacin de datos. Cmo capturar y mostrar informacin desde el usuario y hacia l, y almacenarla o recuperarla, son algunos de los retos con los que los desarrolladores se enfrentan a cada momento. Por esto, es necesario tambin poder contar con formas fciles y rpidas de realizar estas tareas. Silverlight implementa varas tcnicas y modelos que simplifican el desarrollo de aplicaciones orientadas a los datos. Por un lado, podemos usar el concepto de enlazado de datos, que hace referencia a que, sobre la base de los datos que tengamos disponibles y de su estructura, podamos especificar qu controles y componentes los mostrarn y cmo lo harn, as como actualizar esta informacin de vuelta hacia los elementos que originalmente transportaban esta informacin. Otra de las posibilidades brindadas es el uso de
275

7. INTERCONEXIN

LinQ. Tras una modificacin al lenguaje de programacin, se incluye este modelo que nos brinda la posibilidad de realizar consultas sobre objetos XML o bases de datos, pero desde el punto de vista de la programacin orientada a objetos. Esto quiere decir que, mediante el uso de sintaxis de programacin orientada a objetos, es posible ejecutar consultas similares a las encontradas en las bases de datos, haciendo que los distintos objetos creados por cdigo puedan ser filtrados, ordenados y agrupados, entre otras posibilidades.

Enlazado de datos
Esta tcnica, entonces, se refiere a la posibilidad de que los valores contenidos en una entidad contenedora de datos puedan ser ledos y mostrados de manera automtica. Decimos que es de forma automtica ya que, en los casos ms comunes, se suele leer el valor del origen de datos y asignarlo al elemento de la interfaz que queramos que muestre esta informacin.
this.textBoxNombre.Text = persona.Nombre; this.textBoxApellido.Text = persona.Apellido; this.textBoxCorreo.Text = persona.Correo;

Si bien las lneas de cdigo vistas no representan un problema, con grandes volmenes de informacin pueden requerir mucho esfuerzo para su construccin. Adems, pueden incurrir en costos de mantenimiento. Si agregramos o modificramos alguna de las propiedades del objeto contenedor de datos, tendramos que cambiar tambin nuestro cdigo. Al mismo tiempo, si necesitramos hacer que uno de los valores anteriores se mostrase en otra caja de texto y no en la predefinida en el cdigo, sera necesario tener que modificar esas lneas y compilar la aplicacin otra vez. Para solucionar este problema y asociar los datos a los distintos controles de nuestra interfaz, podemos utilizar el enlazado de datos en el cdigo XAML, especificando el nombre de la propiedad del contenedor de datos del cual tomaremos la informacin:
Text={Binding Correo}

Mediante el uso de la clusula Binding, acompaada del nombre de la propiedad de la que se consumir la informacin, la propiedad del control asociado tomar este valor y lo aplicar en tiempo de ejecucin. As, si necesitramos modificar esta informacin (la fuente del dato), slo deberamos cambiar el cdigo XAML sin necesidad de recompilar toda la aplicacin. Veamos cmo podramos aplicar esta forma de enlazado de datos en nuestra aplicacin:
276

Manipular datos

<UserControl x:Class=Capitulo7DataBinding.Page xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml Width=400 Height=300 xmlns:d=http://schemas.microsoft.com/expression/blend/2008 xmlns:mc=http://schemas.openxmlformats.org/markup-compatibility/2006 mc:Ignorable=d> <Grid x:Name=LayoutRoot Background=White> <Grid.RowDefinitions> <RowDefinition Height=0.177*/> <RowDefinition Height=0.187*/> <RowDefinition Height=0.21*/> <RowDefinition Height=0.427*/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width=0.315*/> <ColumnDefinition Width=0.685*/> </Grid.ColumnDefinitions> <TextBox Margin=8,31,82,8 Grid.Column=1 Grid.Row=2 Text={Binding Correo} TextWrapping=Wrap d:LayoutOverrides=Height/> <TextBox Margin=8,24,82,8 Grid.Column=1 Grid.Row=1 Text={Binding Apellido} TextWrapping=Wrap d:LayoutOverrides=Height/> <TextBox Margin=8,21,82,8 Grid.Column=1 Text={Binding Nombre} TextWrapping=Wrap d:LayoutOverrides=Height/> <Button Click=Button_Click HorizontalAlignment=Left Margin=8,0,0,8 VerticalAlignment=Bottom Grid.Column=1 Grid.Row=3 Content=Leer d:LayoutOverrides=Height/> <Button Click=Button_Click_1 HorizontalAlignment=Left Margin=42,0,0,8 VerticalAlignment=Bottom Grid.Column=1 Grid.Row=3 Content=Guardar/> <TextBlock Margin=62.594,0,8.161,8 VerticalAlignment=Bottom Text=Nombre: TextWrapping=Wrap d:LayoutOverrides=Height/> <TextBlock Margin=62.594,0,8.161,8 VerticalAlignment=Bottom Grid.Row=1 Text=Apellido: TextWrapping=Wrap d:LayoutOverrides=Height/> <TextBlock HorizontalAlignment=Right Margin=0,0,7.717,8 VerticalAlignment=Bottom Width=55 Grid.Row=2 Text=Correo: TextWrapping=Wrap d:LayoutOverrides=Height/>

277

7. INTERCONEXIN

</Grid> </UserControl>

Notemos que an no hemos especificado la fuente de datos. Si bien los controles saben el nombre de la propiedad de la cual obtendrn la informacin por mostrar, sta no ha sido especificada an. Para lograr esto, podremos asignar el objeto contenedor de datos al control que incluye los controles que configuramos para que usen enlazado de datos. En este caso, el control Grid es el agrupador de los controles TextBox, y lo usaremos para asignar los datos.
private Persona persona; public Page() { InitializeComponent(); persona = new Persona() { Nombre = Persona 1, Apellido = Apellido 1, Correo = Correo 1 }; } private void Button_Click(object sender, RoutedEventArgs e) { this.LayoutRoot.DataContext = persona; }

Si usamos la propiedad DataContext del control Grid, asignamos el objeto de datos y, como resultado de esta accin, todos los valores sern recolectados y desplegados por los correspondientes controles.

RRR

DATACONTEXT

Debido a que en un principio asignamos un tipo de dato especfico, la propiedad DataContext retornar el mismo tipo de datos que hemos asignado, lo que nos ahorrar lneas de cdigo al tener que transformar nuestros objetos a algn otro tipo especfico, y viceversa.

278

Manipular datos

Figura 30. Valores asignados en forma automtica mediante enlazado de datos.

As como asignamos valores mediante el atributo DataContext, es posible recolectar los cambios de estos valores por medio de la misma propiedad, como vemos en el cdigo inferior. Si dejamos el enlazado de datos tal como lo definimos al principio, por ms que el usuario realice cambios en los valores de la interfaz, al tratar de recolectar la informacin, stos valdrn exactamente lo mismo que en el momento de la asignacin.
persona = (Persona)this.LayoutRoot.DataContext;

Figura 31. Los datos fueron actualizados en la interfaz, pero la propiedad DataContext retorn valores no actualizados.
279

7. INTERCONEXIN

Esto se debe a que es posible especificar la forma en la que los controles con datos enlazados se comportarn ante los cambios. Configuramos el enlace de datos con alguna de las siguientes propiedades basados en el comportamiento que queramos obtener: OneWay: ste es el valor por defecto. Har que el control enlazado modifique su valor slo cuando la fuente de datos sea modificada. TwoWay: actuar tanto cuando la fuente de datos sea modificada as como cuando el control sufra un cambio. De esta forma, si el usuario modificara el texto desplegado en un control, este cambio se vera reflejado en la fuente de datos. OneTime: slo actualizar los controles la primera vez que se asignen los valores desde la fuente de datos. Luego, no se vern afectados por cambios en la fuente de datos y tampoco ejercern cambios sobre ella. Si hacemos una modificacin a nuestros controles enlazados, actualizaremos los valores de la fuente de datos sobre la base de las modificaciones realizadas por el usuario.
<TextBox Margin=8,31,82,8 Grid.Column=1 Grid.Row=2 Text={Binding Correo, Mode=TwoWay} TextWrapping=Wrap d:LayoutOverrides=Height/> <TextBox Margin=8,24,82,8 Grid.Column=1 Grid.Row=1 Text={Binding Apellido, Mode=TwoWay} TextWrapping=Wrap d:LayoutOverrides=Height/> <TextBox Margin=8,21,82,8 Grid.Column=1 Text={Binding Nombre, Mode=TwoWay} TextWrapping=Wrap d:LayoutOverrides=Height/>

Figura 32. En este caso, los datos fueron actualizados en la interfaz, y la propiedad DataContext retorn valores actualizados.
280

Manipular datos

En el ejemplo anterior hemos usado, como tipo de dato base para todos los valores, un string o texto, pero esto no siempre ser de esta manera, ya que a veces se necesitan otro tipo de valores para albergar, por ejemplo, datos numricos, fechas y dems. Si enlazramos datos diferentes al de texto y el usuario introdujera un valor no soportado por ese tipo de datos, por ejemplo, un campo numrico para alojar el precio de un producto, y el usuario escribiera una letra, obtendramos un error en la aplicacin. Esto se debe a que, al tratar de pasar los valores de la interfaz a la entidad asignada, los tipos de datos colapsaran. Para evitar esto, podemos hacer uso de validadores en el enlazado de datos que, si bien no prevendrn del error, s nos avisarn para que nosotros tomemos un curso de accin para solucionarlo. Tengamos en cuenta la siguiente entidad de datos:
public class Persona { public string Nombre { get; set; } public string Apellido { get; set; } public string Correo { get; set; } public int Edad { get; set; } }

Adicionamos el campo Edad, de tipo numrico. En este caso, si el usuario colocase un valor no numrico, producira un error al no poder pasar ese valor a uno que slo acepta nmeros. Lo primero que haremos es agregar un nuevo control TextBox para desplegar un valor numrico desde la fuente de datos.
<TextBox Margin=8,25,82,80 Grid.Column=1 Grid.Row=3 Text={Binding Edad, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true} TextWrapping=Wrap d:LayoutOverrides=Height/>

Veamos que, en la propiedad Text del control, dentro de la declaracin del enlazado de datos previamente usada, ahora hemos agregado dos nuevos atributos:
281

7. INTERCONEXIN

que har las validaciones en relacin con lo introducido por el usuario y el tipo de dato de la fuente de datos; y NotifyOnValidationError, que disparar un evento para notificar que se ha producido un error de validacin. Debido a que hemos asignado la fuente de datos al contenedor de estos controles, es necesario declarar y capturar el evento disparado por el validador desde este punto.
<Grid x:Name=LayoutRoot Background=White BindingValidationError=LayoutRoot_BindingValidationError> <Grid.RowDefinitions> ...

ValidatesOnExceptions,

Notemos la presencia de BindingValidationError. Este evento es el que nos avisar en el momento que alguna validacin falle. Gracias a esto, podremos avisar al usuario que existe un problema para que haga los cambios correpondientes.
private void LayoutRoot_BindingValidationError(object sender, ValidationErrorEventArgs e) { this.mensajeError.Text = Se encontr un error en los datos.; this.mensajeError.Text += Valor: + ((System.Windows.Controls.TextBox)(((System.Windows.RoutedEventArgs) (e)).OriginalSource)).Text; }

Figura 33. Error de validacin capturado y mensaje enviado al usuario.


282

Manipular datos

LinQ
LinQ es una modificacin a los lenguajes de programacin basados en Microsoft .Net Framework 3.5, que permite realizar consultas sobre XML, objetos y bases de datos simulando la sintaxis de SQL transaccional con palabras reservadas y un enfoque orientado a objetos. Es destacable la presencia de LinQ en Silverlight ya que, por el pequeo tamao de la firma instalable en el navegador del cliente, sera vlido asumir que slo contendr funcionalidad mnima y que no podra incluir este tipo de aditamentos. Contar con esta clase de herramientas que pueden maximizar la productividad en el desarrollo hace que, una vez ms, Silverlight est listo para aplicaciones de gran escala. Para ver la potencia de LinQ, asumamos que necesitamos ordenar una lista de elementos en un vector. Si bien contamos con mecanismos propios de .Net Framework, podra existir la posibilidad de que tengamos que implementar nuestra propia forma de ordenamiento. Una de las ms conocidas es el ordenamiento de burbuja.
static void Ordenamiento_Burbuja(int[] array) { long maximo_derecho = array.Length - 1; do { long ultimo_cambio = 0; for (long i = 0; i < maximo_derecho; i++) { if (array[i] > array[i + 1]) { int temp = array[i]; array[i] = array[i + 1]; array[i + 1] = temp; ultimo_cambio = i; } } maximo_derecho = ultimo_cambio; } while (maximo_derecho > 0); }

La funcin antes planteada ordenar un vector de enteros, que tendr como nica tarea posible realizar este trabajo. Ahora veamos lo que podramos lograr con LinQ:
283

7. INTERCONEXIN

int[] vector = new int[] { 10, 4, 5, 35, 23, 56 }; private void Button_Click(object sender, RoutedEventArgs e) { var q = from c in vector orderby c ascending select c; this.Ordenado.ItemsSource = q; }

Si tenemos el mismo vector de nmeros enteros, slo ejecutamos una consulta sobre ese vector, ordenndolo de manera ascendente y asignndolo a un control ListBox. Como podemos ver, para lograr el mismo resultado, la cantidad de cdigo comparado con el ordenamiento por burbuja tpico es sustancialmente menor y ms fcil de entender.

Figura 34. Un vector de enteros ordenado con LinQ.

Pero LinQ puede ir mucho ms lejos y no slo ordenar vectores simples. Teniendo en cuenta que, a pesar de la reduccin del volumen de cdigo, la lgica para ordenar el vector suele ser genrica, LinQ provee otras caractersticas sobre una coleccin de elementos o de objetos. Podramos tener un tipo complejo como el que sigue:
public class Estudiante { public enum Cursos

284

Manipular datos

{ A, B, C } public string Nombre { get; set; } public string Materia { get; set; } public Cursos Curso { get; set; } public string Ciudad { get; set; } public int Nota { get; set; } }

Esta entidad posee diferentes elementos complejos como para invalidar el uso del ordenamiento por burbuja que habamos visto inicialmente, sin tener que modificarlo casi por completo. De cualquier manera, con LinQ podramos solucionar este problema de forma sencilla.
private void Button_Click_1(object sender, RoutedEventArgs e) { var q = from c in estudiantes where (c.Curso == Estudiante.Cursos.A) && (c.Nota >= 4) orderby c.Nota descending select c; this.grillaAlumnos.ItemsSource = q; }

En este caso, de una lista de la entidad Estudiante, seleccionamos slo los alumnos pertenecientes al curso A con una nota superior a 4, y ordenamos el resultado
285

7. INTERCONEXIN

basados en la nota de manera descendente. Como vemos en la siguiente figura, el resultado son los alumnos con el criterio de seleccin previamente formulado.

Figura 35. Lista de estudiantes filtrada con LinQ.

Podemos realizar tantas combinaciones en consultas como si se tratase de una consulta a una base de datos. A continuacin, vemos cada una de las palabras reservadas que podemos usar para obtener informacin de nuestras colecciones de datos: Where: condicionante basado en el predicado de la consulta. Select/SelectMany: operador de proyeccin basado en el predicado de la consulta. Selecciona los elementos resultantes de la consulta como su pariente transaccional. Take/Skip/TakeWhile/SkipWhile: operadores de particin basados en una posicin o en el predicado de la consulta. Join/GroupJoin: conjuncin de dos o ms elementos dentro de la consulta basados en una llave comn. Concat: operador de concatenacin. OrderBy/ThenBy/OrderByDescending/ThenByDescending: operadores de ordenamiento, tanto ascendentes como descendentes. Reverse: operador de ordenamiento que se encarga de revertir el orden de la secuencia original de la consulta. GroupBy: agrupador de elementos basado en una llave de la consulta. Distinct: operador que remueve los elementos duplicados de la consulta. Union/Intersect: operadores que se ocupan de retornar la unin o la interseccin de los elementos en la consulta. Sum/Min/Max/Average: operadores utilizados para hacer clculos matemticos o de comportamiento dentro de la consulta.
286

Manipular datos

Estos operadores pueden ser aplicados a cualquier lista de objetos o a cualquier elemento que soporte la interfaz IEnumerable<>. Los resultados obtenidos con LinQ pueden ser moldeables. Con esto queremos decir que no es necesario que, tras cada consulta, retornemos un nuevo conjunto de elementos de la misma entidad filtrada. Es posible, con LinQ, retornar slo los campos de la entidad que necesitemos para ese momento, como podemos ver en el siguiente ejemplo:
private void Button_Click_2(object sender, RoutedEventArgs e) { var q = from c in estudiantes where (c.Materia == Matematica) select new { c.Nombre, c.Materia }; this.grillaAlumnos.ItemsSource = q; }

En el ejemplo anterior, el resultado slo contendr los nombres y las materias de los estudiantes que cumplan con el criterio de bsqueda, pero no se incluirn los dems elementos de la entidad. LinQ tiene mucho potencial, por lo que no deberemos desestimarlo en nuestros desarrollos. Si bien aqu slo hemos visto la punta de lo que LinQ tiene para ofrecernos, a medida que lo pongamos en prctica reconoceremos que podemos lograr cosas bastante complejas con muy poco cdigo.

RESUMEN
Este captulo nos ha terminado de mostrar la potencia de Silverlight cuando le agregamos cdigo C#. Hemos modificado el estado de los controles y componentes para que se comporten de distintas formas desde el cdigo, aprendimos a guardar y a leer informacin del usuario, enviamos y recibimos informacin por medio de la red con un lector RSS, y utilizamos tecnologas de conexin y transporte de datos para consumir informacin distante. As, Silverlight orientado a animaciones y comportamiento visual se transforma en un Silverlight para el desarrollo de aplicaciones web de alto nivel.

287

 ACTIVIDADES
PREGUNTAS TERICAS
1 En qu casos deberemos usar el objeto WebClient? 2 Qu evento del objeto WebClient deberemos usar si queremos saber el progreso de la descarga del elemento por consumir desde nuestra aplicacin Silverlight 2? 3 Qu versin del lenguaje C# y de Microsoft .Net Framework podemos utilizar en las aplicaciones Silverlight 2? 4 Qu es un HTTPHandler? 5 Cul es el concepto detrs del almacenamiento aislado? 4 Haciendo uso de eventos e hilos de ejecu6 Cmo podemos adquirir mayor capacidad de almacenamiento dentro del rea designada para cada usuario en el almacn aislado? 7 En el almacenamiento aislado, slo se pueden guardar archivos? 8 Por qu no es posible modificar la interfaz grfica de la aplicacin Silverlight 2 desde un segundo hilo de ejecucin? 9 Es posible interactuar con tipos complejos retornados por servicios web desde Silverlight 2? 10 Es posible en Silverlight 2 enlazar datos desde fuentes de datos de forma dinmica? 5 Para saber ms sobre el manejo de hilos de ejecucin, ingrese en el sitio web oficial de MSDN: http://msdn.microsoft.com/es-es. cin, cree un temporizador personalizado. 3 Cree un modelo de objetos propio para almacenar informacin. Recolecte esa informacin ingresada por el usuario y envela a un servicio web para que ste se encargue de almacenarla en una base de datos distante. 2 Para saber ms sobre Windows Communication Foundation, ingrese en http://msdn. microsoft.com y busque informacin.

EJERCICIOS PRCTICOS
1 Intente ampliar el ejemplo de utilizacin de LinQ, incorporando controles XAML con la lista de filtros y permitirle al usuario interactuar con los datos y las bsquedas.

288

Silverlight

Captulo

El navegador y su dominio
El navegador web es el centro neurlgico de ejecucin de Silverlight, que es hospedado por ste junto con otros lenguajes y tecnologas. JavaScript, HTML y ASP.net son algunos de los modelos que viven a travs de nuestro navegador, y pueden ser conectados entre s. En este captulo haremos que Silverlight interactu con estas tecnologas comunes.
Conectar tecnologas Silverlight 2 y el HTML HtmlDocument y HtmlElement HtmlPage HtmlWindow Cookies Modificar CSS Silverlight 2 y JavaScript Llamar funciones Objetos Silverlight para JavaScript Resumen Actividades 290 290 292 300 305 314 317 320 323 324 327 328

SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com

8. EL NAVEGADOR Y SU DOMINIO

CONECTAR TECNOLOGAS
En el entorno del navegador web, trabajan diferentes tecnologas y lenguajes. Por ejemplo JavaScript, un lenguaje interpretado y ejecutado por el navegador que facilita desde la generacin de contenido dinmico hasta validaciones de las entradas del usuario. Junto con JavaScript, podemos encontrar el lenguaje de etiquetas que da vida a la Web, el HTML, as como otras tecnologas tales como las hojas de estilo o el uso de XML. Todo esto es administrado por el navegador del usuario cada vez que ste accede y visualiza una pgina web. Por supuesto, Silverlight tambin es parte de este entorno, ya que trabaja dentro del navegador del cliente y convive con las tecnologas antes mencionadas. El hecho de que Silverlight conviva con otras tecnologas web hace que sea natural encontrarse con la posibilidad de que este software pueda influir e interactuar con ellas, as como stas podran, tambin, modificar el comportamiento de la aplicacin Silverlight creada y hospedada en este entorno comn. As es cmo Silverlight provee una serie de objetos que nos permiten interactuar con nuestras pginas web, desde dentro de la aplicacin Silverlight, y al mismo tiempo, su intrprete, instalado en el navegador cliente y que hace uso del lenguaje JavaScript, permite crear y modificar aplicaciones Silverlight desde fuera de su contenedor. En este captulo veremos, entonces, cmo es posible interactuar con Silverlight desde fuera de l y cmo ste, a su vez, puede modificar el ambiente que lo contiene.

SILVERLIGHT 2 Y EL HTML
Silverlight posee una serie de objetos, clases y componentes que nos permiten interactuar con el entorno donde est contenido. En este caso especfico, con el HTML de la pgina web que contiene nuestra aplicacin web. Si tenemos en cuenta que la aplicacin Silverlight creada se declara en el cdigo HTML por medio de tags que el navegador entienda, entonces la aplicacin es un elemento ms de todo el conjunto de elementos que representan la pgina web. Si vemos el cdigo HTML declarativo usado para incrustar aplicaciones Silverlight en HTML, nos daremos cuenta de que este elemento es uno ms en el conjunto de tags.
<div id=silverlightControlHost> <object data=data:application/x-silverlight-2, type=application/xsilverlight-2 width=100% height=100%> <param name=source value=ClientBin/Capitulo8HTML.xap/> <param name=onerror value=onSilverlightError /> <param name=background value=white />

290

Silverlight 2 y el HTML

<param name=minRuntimeVersion value=2.0.31005.0 /> <param name=autoUpgrade value=true /> <a href=http://go.microsoft.com/fwlink/?LinkID=124807 style=text-decoration: none;> <img src=http://go.microsoft.com/fwlink/?LinkId=108181 alt=Get Microsoft Silverlight style=border-style: none/> </a> </object> <iframe style=visibility:hidden;height:0;width:0;border:0px></iframe> </div>

El cdigo anterior nos muestra que, para que el navegador web pueda mostrar y ejecutar la aplicacin Silverlight, sta debe ser declarada en el lenguaje que el navegador entienda, esto es, HTML, y, por consiguiente, ser posible acceder a este HTML desde la aplicacin Silverlight. A continuacin, podemos ver la lista de clases y objetos disponibles desde Silverlight para interactuar con nuestra pgina HTML. HtmlPage: identifica la pgina HTML actual. Segn dnde est incrustado el control Silverlight, su contexto HTML es representado por este objeto. Este objeto provee las principales funcionalidades para interactuar con la pgina web actual, como capturar informacin del navegador en el que est corriendo la aplicacin, abrir ventanas emergentes, conocer configuraciones de seguridad del navegador, entre otras. BrowserInformation: retorna informacin especfica del navegador, como el tipo de navegador que se est usando, el nombre del navegador web, su versin, etctera. HtmlDocument: representa la pgina HTML, su estructura y tags. HtmlDocument puede ser til en momentos en los que necesitemos modificar los elementos contenidos en nuestra pgina web. HtmlElement: puede ser cualquier elemento HTML contenido en la pgina web. Se pueden usar mtodos como SetAttribute() y SetProperty() para modificar cada elemento, pasando u obteniendo valores al elemento y desde l. HtmlWindow: representa la ventana del navegador, proporcionando mtodos para navegar a otras pginas o saltar entre diferentes marcadores dentro de la misma pgina. HttpUtility: nos otorga un conjunto de herramientas de cdigo para realizar tareas sobre el HTML. Codificar y decodificar los parmetros enviados desde la pgina original hacia una pgina destino. ScriptableTypeAttribute/ScriptableMemberAttribute: atributos que pueden ser aplicados a nuestras clases en Silverlight para hacerlas accesibles desde cdigo JavaScript. ScriptObject: referencia una funcin JavaScript escrita y ejecutada en la pgina web contenedora de la aplicacin Silverlight. Esta referencia puede ser ejecutada desde nuestra aplicacin Silverlight para realizar acciones fuera del contexto de Silverlight.
291

8. EL NAVEGADOR Y SU DOMINIO

HtmlDocument y HtmlElement
Con HtmlDocument es posible modificar e interactuar con la estructura HTML presente en el documento que albergue la aplicacin Silverlight. El siguiente cdigo lee la direccin web desde el navegador y la muestra dentro de nuestra aplicacin Silverlight:
private void Mostrarpagina_Click(object sender, RoutedEventArgs e) { HtmlDocument document = HtmlPage.Document; this.texto1.Text = document.DocumentUri.ToString(); }

Como podemos observar en la Figura 1, la direccin URL donde se ubica la aplicacin web es mostrada en un TextBox.

Figura 1. Direccin URL donde se hospeda la aplicacin Silverlight.

no slo nos otorga algunos datos del navegador y la pgina web en la cual estemos ejecutando nuestra aplicacin, tambin nos permite acceder a los elementos que estn fuera de nuestra aplicacin. Veamos el siguiente cdigo HTML:
HtmlDocument
<body style=height: 100%; margin: 0;> <form id=form1 runat=server style=height: 100%;> <asp:ScriptManager ID=ScriptManager1 runat=server> </asp:ScriptManager> <div style=height: 100%;> <table>

292

Silverlight 2 y el HTML

<tr> <td style=width:500px; height:300px;> <asp:Silverlight ID=Xaml1 runat=server Source=~/ClientBin/Capitulo8HTML.xap MinimumVersion=2.0.31005.0 Width=100% Height=100% /> </td> </tr> <tr> <td> <input type=text id=textBoxExterno value= /> </td> </tr> </table> </div> </form> </body>

Como podemos observar en el cdigo HTML que aparece ms arriba, nuestra aplicacin Silverlight se encuentra dentro de una tabla HTML y, en el fondo de ella, un campo de texto declarado con tags HTML.

Figura 2. La aplicacin Silverlight dentro de una tabla HTML.

Si nos basamos en la estructura anterior, donde hay un elemento HTML fuera de la aplicacin, es posible que accedamos a ese elemento para modificar sus valores.
293

8. EL NAVEGADOR Y SU DOMINIO

private void Button_Click(object sender, RoutedEventArgs e) { HtmlDocument documento = HtmlPage.Document; this.texto2.Text = documento.GetElementById(textBoxExterno).GetAttribute(value).ToString(); }

Mediante el uso de GetElementById, palabra reservada homnima de JavaScript, accedemos al elemento creado por tags HTML en la pgina, haciendo uso del valor incluido en el atributo ID del componente. Luego, usando GetAttribute, referenciamos el atributo del elemento que contenga los valores por capturar. Como vemos en la figura siguiente, el contenido de la caja de texto HTML es pasado dentro de nuestra aplicacin Silverlight.

Figura 3. El valor de la caja de texto HTML es capturado por la aplicacin Silverlight.

Si hacemos uso de la misma tcnica, podemos realizar la accin inversa: enviar informacin a cualquier elemento contenido dentro de la pgina web donde resida nuestra aplicacin Silverlight.
private void Button_Click_1(object sender, RoutedEventArgs e) { HtmlDocument documento = HtmlPage.Document; documento.GetElementById(textBoxExterno).SetAttribute(value, Valor enviado desde Silverlight); }

294

Silverlight 2 y el HTML

En este caso, el texto utilizado en SetAttribute ser alojado en la caja de texto HTML, fuera de la aplicacin Silverlight.

Figura 4. En este caso, la caja de texto HTML fue modificada desde Silverlight.

Pero este tipo de atributos no slo sirve para modificar o leer valores de los controles HTML de la pgina web. El comportamiento, por el contrario, es ms cercano al que podra brindar JavaScript, ya que muchas propiedades no comunes en el tag HTML, pero que s pueden ser accedidas desde JavaScript, tambin pueden ser accedidas y modificadas desde Silverlight. Agreguemos una fila ms a la tabla HTML previamente creada.
<tr> <td> <div id=constructorHTML> </div> </td> </tr>

Como vemos, hemos agregado una etiqueta <div>. Esta etiqueta tiene la particularidad de servir de contenedor de otras etiquetas HTML y, como tal, tambin es posible modificar su estructura HTML desde cdigo JavaScript mediante el uso de la propiedad innerHTML. Entonces, podramos hacer uso de innerHTML desde la aplicacin Silverlight para crear cdigo HTML dentro de esta etiqueta.
private void Button_Click_2(object sender, RoutedEventArgs e)

295

8. EL NAVEGADOR Y SU DOMINIO

{ HtmlDocument documento = HtmlPage.Document; string constructor = Introducir nombre: <input type=\text\ value=\\ id=\nuevoTexto\ style=\width:150px\>; documento.GetElementById(constructorHTML).SetAttribute(innerHTML, constructor); }

Como vemos en el cdigo, construimos elementos HTML sobre la base de una cadena de texto que luego es asignado al atributo innerHTML del tag <div>, haciendo que este texto sea transformado en HTML.

Figura 5. La nueva caja de texto, con un texto descriptivo creado desde Silverlight.

Como este elemento es creado dentro del conjunto de elementos HTML que conforman la pgina web, no sera impedimento, mediante el uso de GetAttribute y el identificador del nuevo control, para recuperar esta informacin una vez que el usuario hubiera completado el campo de texto. En caso de que tengamos que realizar una aplicacin que no slo trabaje con navegadores de la gama de Internet Explorer, podemos hacer uso de otros mecanismos para crear controles de manera dinmica. Por ejemplo, mediante el uso de HtmlElement, objeto que permite la manipulacin de elementos individuales dentro de la pgina HTML.
private void Button_Click_3(object sender, RoutedEventArgs e) {

296

Silverlight 2 y el HTML

HtmlDocument documento = HtmlPage.Document; HtmlElement elemento = documento.CreateElement(INPUT); elemento.SetProperty(type, text); elemento.SetProperty(value, Nuevo control); documento.GetElementById(constructorHTML).AppendChild(elemento); }

Veamos que, en el caso anterior, es necesario definir cada uno de los atributos que representarn el objeto HTML por crear. Inicialmente creamos un elemento de un tipo especfico, un tipo INPUT, tag usado, por lo comn, para definir elementos con los cuales el usuario pueda interactuar. El siguiente paso es definir el tipo de control contemplado dentro de este tag y, por ltimo, definimos un valor por defecto que se visualizar, al comienzo, cuando el control se cree en la pgina web. Por ltimo, adicionamos este nuevo control a la lista de controles hijo del tag <div> con el que antes habamos estado interactuando.

Figura 6. Un nuevo control de texto creado mediante el uso de HtmlElement.

De cualquier manera, no estamos sujetos a crear slo elementos, como botones o cajas de texto, ya que es posible lograr cualquier elemento HTML representado por un tag. El siguiente cdigo muestra cmo crear una imagen siguiendo el mismo patrn de creacin de elementos HTML:
private void Button_Click_4(object sender, RoutedEventArgs e) {

297

8. EL NAVEGADOR Y SU DOMINIO

HtmlDocument documento = HtmlPage.Document; HtmlElement elemento = documento.CreateElement(IMG); elemento.SetProperty(src, http://static.redusers.com.ar/redusers/images/logo.jpg); documento.GetElementById(constructorHTML).AppendChild(elemento); }

Figura 7. Al presionar el botn en Silverlight, se crea una nueva imagen basada en los parmetros establecidos.

Otra posibilidad que otorga el objeto HtmlDocument es la de enviar hacia el servidor toda la informacin contenida dentro de las etiquetas <form> de la pgina web. Por lo general, usamos estas etiquetas para enmarcar todos los controles web cuyo contenido ser enviado al servidor para que luego ste capture la informacin introducida por el usuario. Para entender esto, veamos el siguiente cdigo HTML:
<form id=form1 runat=server style=height: 100%;> <asp:ScriptManager ID=ScriptManager1 runat=server> </asp:ScriptManager> <div style=height: 100%;> ... ... </div> </form>

298

Silverlight 2 y el HTML

Todos los elementos contenidos dentro de las etiquetas <form> son capturados por la pgina y enviados al servidor para su procesamiento. As, un usuario que hubiese interactuado con cajas de texto, listas desplegables y otros controles podra notificar de estos cambios al cdigo que se ejecuta en el servidor. En el caso de ASP.net, es posible analizar estos elementos desde el cdigo creado en el servidor. Ese cdigo podra ser como el que sigue:
<script runat=server> protected void Page_Load(object sender, EventArgs e) { } </script>

En el momento en el que el formulario sea enviado desde el cliente al servidor, este mtodo ASP.net se disparar y, si bien el usuario deber realizar la accin de enviar esta informacin, tambin es posible hacerlo desde Silverlight.
private void Button_Click_5(object sender, RoutedEventArgs e) { HtmlDocument documento = HtmlPage.Document; documento.Submit(); }

Al ejecutar la lnea documento.Submit(), el formulario se enviar al servidor como vemos en la Figura 8 y en la Figura 9, donde el campo de texto, al final de la aplicacin Silverlight, contiene cierta informacin introducida por el usuario. Esta informacin, luego, es enviada y capturada por el cdigo ASP.net.

INNERHTML

La propiedad innerHTML slo es vlida en navegadores compatibles con Internet Explorer, debido a que Microsoft agreg esta funcionalidad al conjunto de sentencias disponibles para JavaScript bajo Internet Explorer. Si usamos innerHTML para nuestros desarrollos, podramos obtener un error en tiempo de ejecucin si el usuario utilizase un navegador no compatible.

299

8. EL NAVEGADOR Y SU DOMINIO

Figura 8. Caja de texto modificada por el usuario.

Figura 9. El valor de la caja de texto es capturado en el servidor una vez que se enva la informacin desde la aplicacin Silverlight.

HtmlPage
El objeto HtmlPage tambin provee una serie de mtodos y funciones para interactuar sobre la pgina web donde Silverlight reside. Si bien hemos utilizado este objeto para obtener una referencia al documento que representa el HTML de la pgina, HtmlPage se encuentra en un nivel superior y representa toda la informacin de la pgina en s, pudiendo generar comportamientos en el navegador. Uno de ellos est ligado a la creacin de ventanas emergentes. Las ventanas emergentes son aquellas que, al ingresar en un sitio o por medio de alguna accin del usuario, son disparadas en una nueva instancia del navegador web, apareciendo una segunda ventana que nos redirige a otra
300

Silverlight 2 y el HTML

pgina. Con el uso de HtmlPage, es posible generar este comportamiento. La creacin de una ventana emergente posee caractersticas similares a las presentadas en el cdigo JavaScript. Veamos el siguiente cdigo para entender mejor lo que queremos lograr.
<script language=javascript type=text/javascript> function AbrirVentana() { var opciones = width=300; height=300;; window.open(http://www.redusers.com, nuevaVentana, opciones); } </script>

Notaremos que para crear una nueva ventana es necesario, como primer parmetro, definir la direccin web a la cual navegar esa ventana, un nombre que la identifique y una serie de parmetros que definirn su comportamiento. Como resultado, obtendremos una nueva instancia del navegador, como vemos en la siguiente figura:

Figura 10. Una ventana emergente desde JavaScript.

Si entendemos este concepto, veremos que la forma de realizar esto desde Silverlight es similar. Veamos el cdigo:
HtmlPopupWindowOptions opciones = new HtmlPopupWindowOptions(); opciones.Width = 300;

301

8. EL NAVEGADOR Y SU DOMINIO

opciones.Height = 300; HtmlPage.PopupWindow(new Uri(http://www.redusers.com), _blank, opciones);

El resultado de este cdigo ser idntico al obtenido con JavaScript, donde tambin deberemos definir una direccin URL, el nombre de la nueva instancia y una serie de opciones para configurar la ventana emergente. Las opciones de configuracin de la ventana emergente pueden ser importantes a la hora de obtener un comportamiento visual especfico. Podemos ver la lista de opciones dentro del objeto HtmlPopupWindowOptions a continuacin: Height: determina el alto de la ventana en pixeles. Width: determina el ancho de la ventana en pixeles. Top: establece la posicin, en pixeles, de la ventana emergente a partir del borde superior de la pantalla. Left: establece la posicin, en pixeles, de la ventana emergente a partir del borde izquierdo de la pantalla. Directories: esta opcin muestra u oculta los marcadores o vnculos del navegador para la ventana emergente. Location: muestra u oculta la barra de navegacin para la ventana emergente. Menubar: muestra u oculta las opciones del navegador (mens). Resizeable: permite la capacidad de que el usuario pueda cambiar, o no, de tamao la ventana emergente una vez creada. Scrollbars: esta opcin muestra u oculta las barras de desplazamiento, tanto horizontales como verticales. Status: muestra u oculta la barra de estado del navegador. Toolbar: esta opcin muestra u oculta la barra de herramientas del navegador en la ventana emergente. Aplicamos los atributos anteriores como en el siguiente cdigo:
HtmlPopupWindowOptions opciones = new HtmlPopupWindowOptions(); opciones.Directories = false; opciones.Height = 300; opciones.Left = 10; opciones.Location = false; opciones.Menubar = false; opciones.Resizeable = false; opciones.Scrollbars = false;

302

Silverlight 2 y el HTML

opciones.Status = false; opciones.Toolbar = false; opciones.Top = 50; opciones.Width = 300; HtmlPage.PopupWindow(new Uri(http://www.redusers.com), _blank, opciones);

Figura 11. La posicin y las propiedades configuradas en una nueva ventana.

Debido a que las ventanas emergentes suelen ser intrusivas, o no necesariamente aceptadas por todos los usuarios, los navegadores actuales cuentan con mecanismos para bloquear estas ventanas, haciendo que no puedan abrirse a menos que el usuario especifique lo contrario. Debido a esto, si ejecutamos el cdigo en forma directa y el navegador del cliente cuenta con una herramienta de bloqueo de ventanas emergentes, no podremos lanzar esta ventana y, por consiguiente, la funcionalidad que pudiramos haber querido implementar se vera frenada. Para asegurarnos de que esto no pase, o por lo menos poder avisarle al usuario que necesitar realizar una accin especfica para permitir las ventanas emergentes, es posible hacer uso del siguiente cdigo:
if (HtmlPage.IsPopupWindowAllowed) { HtmlPopupWindowOptions opciones = new HtmlPopupWindowOptions(); ... ... HtmlPage.PopupWindow(new Uri(http://www.redusers.com), _blank, opciones); }

303

8. EL NAVEGADOR Y SU DOMINIO

else { this.mensaje.Text = No se permiten ventanas emergentes.; }

La propiedad IsPopupWindowAllowed nos permitir saber si el navegador web del cliente tiene activado el bloqueo de ventanas emergentes pudiendo, como en el ejemplo de la figura siguiente, avisarle al usuario de este impedimento.

Figura 12. As se muestra al usuario un mensaje sobre el bloqueo de ventanas emergentes.

Cabe mencionar que adems de abrir una ventana emergente dentro de su parmetro de retorno, HtmlPage.PopupWindow devuelve una referencia del tipo HtmlWindow. Con esta referencia, es posible modificar el comportamiento de la ventana antes abierta de la misma forma que lo haramos desde cdigo JavaScript. En el siguiente cdigo de ejemplo, una vez creada la nueva ventana emergente, si el usuario presiona sobre el segundo botn de la aplicacin Silverlight, redirigiremos el contenido de la ventana a otro sitio web.
HtmlWindow window; private void Button_Click(object sender, RoutedEventArgs e) { if (HtmlPage.IsPopupWindowAllowed) {

304

Silverlight 2 y el HTML

HtmlPopupWindowOptions opciones = new HtmlPopupWindowOptions(); ... ... ... window = HtmlPage.PopupWindow(new Uri(http://www.redusers.com), _blank, opciones); } else { this.mensaje.Text = No se permiten ventanas emergentes.; } } private void Button_Click_1(object sender, RoutedEventArgs e) { window.Navigate(new Uri(http://www.bing.com)); }

Figura 13. Una vez creada la ventana, con el segundo botn la pgina es redirigida a un nuevo sitio web.

HtmlWindow
Para extender lo explicado en el apartado anterior, diremos que HtmlWindow representa una referencia a una ventana del navegador. sta puede ser una ventana emergente o la misma ventana principal donde se ejecuta la aplicacin Silverlight. Adems de poder redirigir la pgina a un nuevo destino, HtmlWindow nos otorga algunos elementos ms con los cuales trabajar.
305

8. EL NAVEGADOR Y SU DOMINIO

Por ejemplo, podramos necesitar requerir informacin por parte del usuario usando ventanas especficas del navegador y no creando las nuestras dentro de la aplicacin Silverlight. La ventaja de realizar esto reside en que esos cuadros de dilogo pueden bloquear el uso de la pgina hasta que el usuario lo cierre. Al bloquear la interaccin con la pgina, podemos asegurarnos de que el usuario siga el flujo de nuestra aplicacin y no evada ciertas reglas necesarias en nuestro cdigo. El siguiente cdigo otorga la posibilidad de enviar una alerta al usuario en forma de cuadro de dilogo.
private void Button_Click_2(object sender, RoutedEventArgs e) { HtmlWindow ventanaPrincipal = HtmlPage.Window; ventanaPrincipal.Alert(Esta es una alerta desde Silverlight); }

Primero, tomamos la instancia de la ventana del navegador y, luego, mediante el uso de Alert() (homnimo de JavaScript), disparamos un mensaje al usuario.

Figura 14. Mensaje de alerta desde Silverlight.

Si intentamos acceder a cualquier elemento de la pgina web o de la aplicacin Silverlight mientras que esta ventana se encuentre activa, notaremos que no es posible hacerlo, por lo que la nica alternativa o curso de accin consiste en presionar dicho elemento. Es posible extender los mensajes de alerta para pedirle al usuario confirmaciones sobre ciertas acciones. Por ejemplo, podramos desplegar un cuadro de dilogo con dos opciones para que el usuario eligiese y, basados en su eleccin, actuar como corresponda.

Figura 15. Cuadro de dilogo con dos opciones seleccionables. private void Button_Click_3(object sender, RoutedEventArgs e) {

306

Silverlight 2 y el HTML

HtmlWindow ventanaPrincipal = HtmlPage.Window; if (ventanaPrincipal.Confirm(Est seguro de seguir adelante?)) { this.mensaje.Text = Usted presion SI; } else { this.mensaje.Text = Usted presion NO; } }

Si hacemos uso del mtodo Confirm(), podremos mostrar un cuadro de dilogo con dos opciones seleccionables por parte del usuario, que ste podr aceptar o cancelar. Si la respuesta por parte del usuario fuera positiva, Confirm() retornar True (verdadero) y si no, False (falso). En la Figura 16, se muestran los dos cursos de accin sobre la base de la seleccin del usuario.

Figura 16. A la izquierda, el usuario presion el botn Aceptar y a la derecha el usuario presion el botn Cancelar.

Podemos ir todava un paso ms all y realizar preguntas especficas al usuario, dejando que ste responda con libertad, introduciendo su respuesta en una caja de texto del mismo dilogo. Lo hacemos de la siguiente manera:
private void Button_Click_4(object sender, RoutedEventArgs e) {

307

8. EL NAVEGADOR Y SU DOMINIO

HtmlWindow ventanaPrincipal = HtmlPage.Window; this.mensaje.Text = ventanaPrincipal.Prompt(Le gusta Silverlight?); }

En este caso, el cuadro de dilogo se mostrar con el mensaje contenido dentro del mtodo Prompt() y retornar un tipo de dato de texto que contiene la respuesta del usuario. En la Figura 17, podemos ver el mensaje que se muestra al usuario, donde podr escribir la respuesta, y en la Figura 18 observamos que la respuesta es escrita dentro de la aplicacin Silverlight.

Figura 17. Cuadro de dilogo con una pregunta enviada al cliente.

Figura 18. Lo escrito por el usuario es reflejado en la aplicacin Silverlight.

En este mismo captulo pudimos abrir una nueva ventana emergente haciendo uso de PopupWindow(), pero tambin es posible que redirijamos la pgina web actual hacia otro destino web sin la necesidad de abrir una ventana nueva que pueda ser bloqueada por el navegador.
private void Button_Click_5(object sender, RoutedEventArgs e) { HtmlWindow ventanaPrincipal = HtmlPage.Window;

308

Silverlight 2 y el HTML

ventanaPrincipal.Navigate(new Uri(http://www.bing.com)); }

En este caso, estableciendo la pgina de navegacin, en el momento que el usuario presione el botn de la aplicacin Silverlight, el navegador se dirigir a la nueva pgina.

Figura 19. A la izquierda, la aplicacin Silverlight. A la derecha, el mismo navegador una vez que el usuario presion el botn de navegacin.

Si fuera necesario, en lugar de lanzar la navegacin en la pgina actual donde reside la aplicacin Silverlight, podramos abrir una nueva pgina, similar a la generada por PopupWindow(), pero sin que el navegador bloquee dicha ventana, ya que sta no tendra las mismas cualidades. Por ejemplo, no podramos modificar los valores de la ventana emergente como el caso de PopupWindow().Utilizando el atributo _blank, la ventana se visualizar en una nueva ventana.
private void Button_Click_5(object sender, RoutedEventArgs e)

RRR

TEXTO EN BOTONES

El texto de los botones del cuadro de dilogo Confirm() depender directamente del idioma del navegador web que est usando el usuario, as como tambin de su versin y su tipo. No se puede, en ningn caso, modificar por cdigo estos valores.

309

8. EL NAVEGADOR Y SU DOMINIO

{ HtmlWindow ventanaPrincipal = HtmlPage.Window; ventanaPrincipal.Navigate(new Uri(http://www.bing.com), _blank); }

Tambin podemos, con HtmlWindow, navegar entre marcadores HTML. Los marcadores HTML son definidos por el tag <a> y una propiedad que identifique el nombre de este marcador.
<a name=MiMarcador>

Esto permitir que, en la barra de navegacin del navegador web, si especificamos este marcador, la pgina nos muestre esa zona.
<asp:ScriptManager ID=ScriptManager1 runat=server></asp:ScriptManager> <div style=height:100%;> <asp:Silverlight ID=Xaml1 runat=server Source=~/ClientBin/Capitulo8HTML3.xap MinimumVersion=2.0.31005.0 Width=100% Height=100% /> </div> <br /> ... ... <br /> <a name=MiMarcador></a> <br /> Marcador HTML

Vemos, en el cdigo anterior, que el marcador se encuentra al final de la pgina HTML y nuestra aplicacin Silverlight, en la parte superior. Desde Silverlight, podremos navegar hasta ese marcador de la siguiente forma:
private void Button_Click_1(object sender, RoutedEventArgs e) { HtmlWindow paginaPrincipal = HtmlPage.Window; paginaPrincipal.NavigateToBookmark(MiMarcador); }

310

Silverlight 2 y el HTML

Notemos la concordancia entre el nombre del marcador HTML y el nombre utilizado en la lnea de cdigo Silverlight. Podemos ver el resultado en la siguiente figura.

Figura 20. La pgina muestra el marcador HTML disparado desde Silverlight.

Podemos extender este ejemplo simple para lograr que, sobre la base de los marcadores, podamos cargar diferentes controles Silverlight contenidos en nuestra aplicacin. Al hacer esto, podemos dar mayor facilidad de uso sobre la aplicacin. Pensemos en una aplicacin que tenga diferentes estados o pginas internas que se vayan mostrando durante la interaccin con el usuario. El usuario podra querer marcar una pgina especfica de la aplicacin para luego acceder directamente a esa parte de la aplicacin. Sin embargo, debido a que cada vez que se carga la aplicacin esto se har desde el inicio, ser difcil saber qu parte es la que quiere ver el usuario. Pero, aplicando marcadores a la aplicacin, es posible conseguir esto. Nuestro primer paso ser agregar un nuevo control Silverlight a la solucin. El siguiente paso ser modificar el cdigo que inicia la aplicacin Silverlight (App.xaml.cs) de la siguiente forma:
private Grid controlPrincipal = new Grid(); private void Application_Startup(object sender, StartupEventArgs e) { this.RootVisual = controlPrincipal; if (String.IsNullOrEmpty(HtmlPage.Window.CurrentBookmark)) { controlPrincipal.Children.Add(new Page()); }

311

8. EL NAVEGADOR Y SU DOMINIO

else { try { Type type = this.GetType(); Assembly assembly = type.Assembly; UserControl controlDestino = (UserControl)assembly.CreateInstance( HtmlPage.Window.CurrentBookmark); controlPrincipal.Children.Add(controlDestino); } catch { controlPrincipal.Children.Add(new Page()); } } } public static void Navegar(UserControl controlDestino) { HtmlPage.Window.NavigateToBookmark(controlDestino.GetType().FullName); }

El cdigo utiliza mecanismos de reflexin sobre los componentes para determinar qu control instanciar, basndose en el nombre contenido en el marcador del navegador web. Las siguientes lneas reconocen este nombre, buscan el control que corresponda, generando una instancia, y sobrescriben el aspecto visual original del control.
Assembly assembly = type.Assembly; UserControl controlDestino = (UserControl)assembly.CreateInstance( HtmlPage.Window.CurrentBookmark); controlPrincipal.Children.Add(controlDestino);

Adems, hemos agregado un mtodo esttico que se encargar de hacer navegar la pgina web al marcador designado, utilizando como nombre del marcador el nombre de instancia del control. Esto nos permitir realizar el siguiente cdigo desde cualquier otro control Silverlight en el proyecto.
312

Silverlight 2 y el HTML

private void Button_Click(object sender, RoutedEventArgs e) { App.Navegar(new Pagina2()); }

En la Figura 21 y en la Figura 22, podemos ver ejemplos con el resultado de aplicar este comportamiento a un proyecto.

Figura 21. La aplicacin naveg hasta el segundo marcador, mostrando un contenido nuevo.

Figura 22. Al presionar sobre el botn contenido en el control anterior, ste navegar a la pgina principal.
313

8. EL NAVEGADOR Y SU DOMINIO

Prestemos atencin al marcador que se genera por la aplicacin Silverlight. La primera parte antes del punto hace referencia al nombre del ensamblado. Este nombre podemos obtenerlo desde las propiedades del proyecto.
#Capitulo8HTML3.Pagina2

La segunda parte, despus del punto, se refiere al nombre del control de usuario o clase que manejar ese control. Deberemos tener en cuenta esto para poder generar, de manera correcta, la instancia del control que se va a visualizar.

Figura 23. Propiedades del proyecto Silverlight, donde encontramos el nombre del ensamblado.

Cookies
Las cookies son archivos de texto que se alojan en el equipo del cliente. Casi siempre, son usados para dejar informacin del usuario para luego reutilizarla segn la necesidad. Los casos ms comunes de uso de cookies los podemos encontrar en aquellos sitios web en los que, al ingresar, nos preguntan si deseamos que nos recuerden, por ejemplo, nuestro nombre de usuario y contrasea para validar nuestra entidad, para que no debamos volver a colocarlos la prxima vez que ingresemos. Estos sitios dejan un archivo de texto con valores y fecha de expiracin en nuestra computadora, que leern posteriormente para as recuperar eso que haban almacenado. Desde una aplicacin Silverlight es posible, tambin, leer cookies que hayan sido creadas por el sitio web donde sta trabaja o crear estos elementos para el mismo sitio web. No debemos comparar las cookies con la caracterstica de almacenamiento aislado provista por Silverlight. Si bien la capacidad de las cookies para almacenar informacin
314

Silverlight 2 y el HTML

es limitada, estos elementos se guardan en el equipo del cliente y pueden ser compartidos con otros ambientes de desarrollo. Estas cookies podran ser manipuladas desde una aplicacin ASP.net, como por JavaScript. Por este motivo, las cookies pueden convertirse en un buen canal de comunicacin entre las distintas plataformas. En el siguiente ejemplo, crearemos una cookie desde ASP.net, que leeremos y modificaremos desde Silverlight. Lo primero ser crear la estructura y el cdigo ASP.net.
<asp:Button ID=Button1 runat=server Text=Crear Cookie onclick=Button1_Click /> &nbsp;<asp:Button ID=Button2 runat=server Text=Ver Cookie onclick=Button2_Click /> <br /> <asp:Label ID=mensaje runat=server Text=Valor del Cookie: FontNames=Arial></asp:Label>

Aqu creamos dos botones, uno para crear la cookie y el otro para leerla. Los valores sern desplegados en el campo de texto que se encuentra declarado al final de las lneas anteriores. Para crear cookies desde ASP.net, escribiremos el siguiente cdigo:
protected void Button1_Click(object sender, EventArgs e) { Response.Cookies.Add(new HttpCookie(CookieSilver, 1234)); } protected void Button2_Click(object sender, EventArgs e) { this.mensaje.Text = Valor del Cookie: + Request.Cookies[CookieSilver].Value.ToString(); }

El primer mtodo crea una cookie llamada CookieSilver, que contiene el valor 1234. El segundo mtodo lee y escribe el contenido de la cookie en el campo de texto. Una vez terminado este paso, podremos tomar esta cookie desde Silverlight. En el evento de presionado del botn, agregaremos el cdigo de lectura y recoleccin de la cookie.
private void Button_Click(object sender, RoutedEventArgs e) { string[] cookies = HtmlPage.Document.Cookies.Split(;);

315

8. EL NAVEGADOR Y SU DOMINIO

foreach (string cookie in cookies) { string[] valores = cookie.Split(=); if (valores.Length == 2) { if (valores[0].ToString() == CookieSilver) { this.mensaje.Text = Valor del Cookie: + valores[1]; break; } } } }

Hemos recolectado toda la informacin de las cookies disponibles mediante la lnea:


string[] cookies = HtmlPage.Document.Cookies.Split(;);

Debido a que podra haber ms de una cookie, cada una de stas se separarn mediante el identificador de ; (punto y coma). Adems, las cookies sern almacenadas con la estructura [Nombre]=[Valor], por lo que, delante del signo igual encontraremos el nombre de la cookie y seguido, el valor almacenado. Al ejecutar el cdigo, obtendremos algo similar a lo siguiente.

Figura 24. La cookie fue recolectada por la aplicacin Silverlight.


316

Silverlight 2 y el HTML

Por supuesto, tambin es posible crear o sobrescribir una cookie ya existente desde una aplicacin Silverlight. Para esto, es necesario utilizar un modelo diferente que no incluye el uso de HtmlPage.Document.Cookies. En este caso, usaremos SetProperty, modificando el valor de la propiedad cookie del navegador.
private void Button_Click_1(object sender, RoutedEventArgs e) { DateTime fechaExspiracion = DateTime.Now + TimeSpan.FromDays(7); string nuevoCookie = CookieSilver=Nuevo Valor;expires= + fechaExspiracion.ToString(R); HtmlPage.Document.SetProperty(cookie, nuevoCookie); }

Notemos que, adems del valor de la cookie, tambin es posible especificar una fecha de expiracin. Esto quiere decir que, si agregamos una fecha a la cookie, sta se mantendr disponible hasta esa fecha. En caso de no especificar una fecha, la cookie se eliminar en el momento en el que abandonemos la pgina que la cre. En la Figura 25, podemos observar que el valor de la cookie modificada desde la aplicacin Silverlight tambin es reconocido desde ASP.net.

Figura 25. La nueva cookie es reconocida por ASP.net.

Modificar CSS
Las hojas de estilo, tambin conocidas como CSS, pueden ser alteradas desde la aplicacin Silverlight. Debido a que tenemos acceso al modelo de objetos de la
317

8. EL NAVEGADOR Y SU DOMINIO

pgina HTML, cualquier elemento presente en sta podra ser cambiado desde nuestra aplicacin. En el caso del uso de estilos, puede resultar de utilidad cuando necesitemos informar al usuario de algn acontecimiento modificando la tipografa o los colores del elemento. A continuacin, veamos dos estilos creados en la pgina donde se ejecutar nuestra aplicacin:
<style type=text/css> .estilo1 { font-family: Arial; font-size: larger; color: Blue; } .estilo2 { font-family: Verdana; font-size: smaller; color: Green; } </style>

Estos estilos presentan una tipografa especfica para cada uno, as como un tamao de letra y un color especial. Apliquemos el primer estilo a un texto en HTML.
<span class=estilo1 id=texto>Texto con estilos</span>

En este caso, mediante el uso de class, asignamos el primer estilo a la frase Texto con estilos. Podemos ver el resultado en la siguiente imagen:

_`

DE HTML A CSS

El desarrollo web ha evolucionado tanto a lo largo de los aos que la aplicacin de los formatos visuales a textos, imgenes, colores de fondo, posicin de distintos elementos y otros aspector pas de ser declarado con etiquetas HTML al uso total de las hojas de estilo. Al momento de disear nuestros sitios web, es una buena prctica aplicar esta tcnica por sobre el uso de tags HTML.

318

Silverlight 2 y el HTML

Figura 26. El texto se muestra con las caractersticas del primer estilo creado.

Si tomamos el elemento desde la pgina web desde su HTML, mediante el identificador del elemento, estaremos en posicin de modificar el estilo por otro de la lista de estilos creados con anterioridad, una vez presionado el botn en la aplicacin Silverlight.
private void Button_Click(object sender, RoutedEventArgs e) { HtmlPage.Document.GetElementById(texto).CssClass = estilo2; }

Figura 27. El formato de la frase cambi de acuerdo con el segundo estilo declarado.
319

8. EL NAVEGADOR Y SU DOMINIO

Otra posibilidad, si no contamos con una estructura de estilos predefinida, es la de modificar los valores de los estilos en el elemento HTML, utilizando el nombre de la propiedad que hace referencia al estilo que queramos modificar.
private void Button_Click_1(object sender, RoutedEventArgs e) { HtmlElement etiqueta = HtmlPage.Document.GetElementById(texto2); etiqueta.SetStyleAttribute(border, dashed 3px black); etiqueta.SetStyleAttribute(color, red); }

Por cada estilo que deseemos aplicar, necesitamos realizar una llamada al mtodo SetStyleAttribute(), especificando el nombre del estilo y su valor. Observemos, en la siguiente figura, cmo se visualiza el elemento HTML antes de aplicar un estilo y cmo queda luego su posterior transformacin.

Figura 28. A izquierda, vemos una etiqueta sin estilo alguno. Al procesar el cdigo Silverlight, ste aplica los estilos especificados.

SILVERLIGHT 2 Y JAVASCRIPT
As como hemos podido interactuar con el HTML contenedor de la aplicacin Silverlight, tambin es posible hacerlo con el cdigo JavaScript que se ejecuta en el navegador. Esta caracterstica puede resultar muy valiosa si tenemos en cuenta el uso actual que se le da a la Web y todas las tecnologas involucradas. Por ejemplo, la implemen320

Silverlight 2 y JavaScript

tacin de A.J.A.X., tecnologa que le da vida a la Web 2.0, se nutre profundamente de JavaScript, por lo que tener control sobre este lenguaje, desde Silverlight y hacia l, puede potenciar mucho ms las posibilidades de desarrollo de aplicaciones web. Como primera instancia, asociaremos un evento JavaScript a un elemento HTML que, cuando se ejecute, ser capturado por la aplicacin Silverlight para manejar este proceso.
private void Button_Click(object sender, RoutedEventArgs e) { HtmlElement elemento = HtmlPage.Document.GetElementById(contenedor); elemento.AttachEvent(onclick, BotonCliente_Click); } private void BotonCliente_Click(object sender, HtmlEventArgs e) { ... ...

Las lneas anteriores toman un elemento HTML, para este caso, un botn, y adjuntan, al evento OnClick de JavaScript para ese botn, un manejador que se encontrar trabajando en la aplicacin Silverlight. Cuando el usuario presione sobre el botn HTML, el mtodo BotonCliente_Click se disparar y podremos ejecutar nuestro cdigo.

Figura 29. El evento fue disparado desde el cliente.

Una vez disparado, podramos ejecutar la lgica de la aplicacin como para llamar a servicios web que retornen informacin, o construir nuevo HTML para el usuario. Esto puede convertirse en una herramienta poderosa si quisiramos encapsular lgi321

8. EL NAVEGADOR Y SU DOMINIO

ca de cdigo dentro de un lenguaje comn como C# o cualquiera que utilicemos con Microsoft .Net. Pensemos que, muchas veces, la depuracin de cdigo JavaScript puede resultar compleja al extremo, incluso lenta, a medida que este cdigo sube en dificultad. Conectarse a servicios web podra requerir de cientos de lneas de cdigo, incluyendo el anlisis del XML retornado por ste, as como el manejo de errores de conexin y dems. Por otro lado, podramos llevar esta lgica a un componente Silverlight sin interfaz visual que se encargue de capturar cada uno de los eventos producidos en JavaScript por el cliente y manejarlos como si se tratase de una aplicacin creada con Microsoft .Net. Esto podra ahorrarnos tiempo y esfuerzo, as como darnos la posibilidad de realizar mantenimiento futuro al cdigo de forma mucho ms eficiente. Los controles HTML cuentan con una serie de eventos a los que podemos subscribir los eventos Silverlight. stos se listan a continuacin: onchange: este evento se disparar cuando el control asociado sufra una modificacin. En el caso de cajas de texto, si el usuario modifica su contenido; y en listas desplegables, si otro elemento de la lista es seleccionado. En la mayora de los casos, el control deber perder el foco para que el evento aplique. onclick: se dispara cuando el usuario presiona el elemento con el mouse. onmouseover: ste se disparar cuando el mouse pase por arriba del elemento. Junto con los valores pasados por argumento, se podrn encontrar las coordenadas por las cuales el mouse se mueve. onmouseout: en el momento en el que el mouse deje la superficie del control HTML, este evento nos avisar. onkeydown: si el usuario presiona una tecla cuando est dentro de un elemento, por lo general representado por una caja de texto, podremos saber qu tecla es la que est presionando. onkeyup: si el usuario deja de presionar una tecla del teclado, el evento nos avisar. onkeypress: si el usuario presion y solt una tecla, este evento se disparar. onfocus: este evento ser ejecutado cada vez que un control tome el foco. Esto es, que el cursor de escritura est sobre l o si el usuario hubiera presionado con el botn del mouse sobre el control para conseguir el foco. onblur: cada vez que un control pierda el foco, se disparar este evento. onload: se dispara cuando la pgina termina de cargar todo su contenido. onunload: cada vez que la pgina sea destruida, el evento nos avisar. Este evento asume que la pgina ser descargada de la memoria del navegador cuando naveguemos a otra pgina o cuando presionemos un vnculo que haga que el contenido de la pgina se recargue. Por consiguiente, podramos subscribirnos a cualquiera de los eventos antes listados. Debemos tener en cuenta que algunos eventos slo son soportados por ciertos navegadores, por lo que deberamos utilizarlos con cuidado.
322

Silverlight 2 y JavaScript

Llamar funciones
Como dijimos, tambin es posible llamar a funciones JavaScript desde cdigo Silverlight. Esto nos ser de gran utilidad en casos en los que tengamos sitios web ya implementados, con lgica incluida en lneas de cdigo JavaScript, y queramos extender esa funcionalidad desde Silverlight. Lo primero que necesitamos es algo de cdigo JavaScript para poder utilizarlo desde Silverlight.
<script language=javascript type=text/javascript> function MostrarMensaje(mensaje) { alert(mensaje); } </script>

En este caso, slo mostraremos un mensaje emergente, pasando un parmetro que representa el texto por mostrar. Desde Silverlight, usaremos el objeto HtmlPage y HtmlWindow para capturar el cdigo JavaScript y ejecutarlo.
HtmlPage.Window.Invoke(MostrarMensaje, Mensaje desde Silverlight);

El primer parmetro del mtodo Invoke() especifica el nombre de la funcin JavaScript por ejecutar. El segundo y todos los siguientes representan cada uno de los parmetros que la funcin JavaScript pudiera necesitar. As, si tenemos ms de un parmetro que pasar a la funcin JavaScript, podremos colocarlos separados por comas. Como vemos en la siguiente figura, el mensaje de alerta es ejecutado en forma correcta.

Figura 30. Al presionar el botn, Silverlight llama y ejecuta la funcin JavaScript.

Tambin es posible utilizar otra forma de referenciar y de ejecutar cdigo JavaScript. La siguiente lnea har el mismo trabajo que lo planteado en las lneas anteriores:
ScriptObject script = (ScriptObject)HtmlPage.Window.GetProperty(MostrarMensaje); script.InvokeSelf(Mensaje desde Silverlight. Nueva forma);

323

8. EL NAVEGADOR Y SU DOMINIO

En este caso, tomamos como una propiedad de la ventana actual el nombre de la funcin JavaScript y transformamos el resultado a un tipo ScriptObject, que albergar la funcin y su funcionalidad. En la Figura 31, observamos que el mensaje se despliega de la misma forma que en el caso anterior.

Figura 31. Utilizando otra forma de ejecutar cdigo, obtenemos similares resultados.

Objetos Silverlight para JavaScript


Silverlight tambin puede exponer mtodos y funciones internas, como objetos JavaScript. En los apartados anteriores trabajamos con eventos y los ejecutamos de un lado y del otro, haciendo que Silverlight fuera el centro de atencin, ya que ste se encargaba de la ejecucin de funciones JavaScript, as como de la captura de eventos desde el navegador cliente. Por otro lado, es posible dar mayor protagonismo a JavaScript haciendo que Silverlight exponga sus mtodos y funciones para que sean consumidos desde el cdigo cliente. Esta posibilidad nos acercara ms al concepto de usar Silverlight como un proveedor de funcionalidad compleja en casos donde la misma implementacin por parte de JavaScript acarreara mucho ms esfuerzo. Para lograr esto, es necesario decorar, con un atributo, la clase Silverlight que se expondr hacia JavaScript y, con un segundo atributo, cada mtodo o funcin que necesitemos exponer.
[ScriptableType()] public partial class Page : UserControl { public Page() { InitializeComponent(); HtmlPage.RegisterScriptableObject(Silver, this); } [ScriptableMember()] public void MostrarMensaje(string mensaje) { this.txtMensaje.Text = mensaje; } }

324

Silverlight 2 y JavaScript

La primera lnea, ScriptableType(), marca la clase como un tipo que podr ser consumido desde JavaScript. La siguiente lnea:
HtmlPage.RegisterScriptableObject(Silver, this);

La lnea anterior se encarga de registrar el cdigo JavaScript que servir de interfaz entre Silverlight y el cdigo JavaScript que consuma esta funcionalidad. Para esto, es necesario especificar un nombre de objeto y la clase que se usar como punto de entrada del script. Por su parte, la lnea ScriptableMember() hace referencia a los mtodos y funciones que podrn ejecutarse desde JavaScript. Podremos tener tantos ScriptableMember() como funciones o mtodos queramos exponer. Una vez expuesta esta informacin, podremos consumirla de la siguiente forma:
<script type=text/javascript> function Mostrar() { var micontrol = document.getElementById(AplicacionSilverlight); micontrol.content.Silver.MostrarMensaje(Mensaje desde JavaScript.); } </script>

El cdigo JavaScript anterior captura el objeto Silverlight embebido en la pgina web. Este control se identifica mediante el uso del atributo ID dentro de su propia declaracin, como podemos ver en el siguiente cdigo:
<object id=AplicacionSilverlight data=data:application/x-silverlight-2, type=application/x-silverlight-2 width=400 height=200> <param name=source value=ClientBin/Capitulo8JavaScript2.xap/> <param name=onerror value=onSilverlightError /> ... ...

Luego, se utiliza la referencia al objeto creado desde Silverlight, llamado Silver, el cual contiene la funcin MostrarMensaje(). La funcin JavaScript Mostrar() es llamada para este caso desde el evento onclick de un botn HTML.
<input type=button value=Mostrar mensaje onclick=Mostrar(); />

325

8. EL NAVEGADOR Y SU DOMINIO

Figura 32. Al presionar el botn, el mensaje enviado desde JavaScript se muestra en Silverlight.

Tambin es posible crear objetos ms complejos para que sean consumidos desde JavaScript. Podemos exponer una clase por completo y que sta pueda ser instanciada y consumida desde el cdigo JavaScript. Veamos la siguiente clase:
[ScriptableType()] public class Sumar2 { [ScriptableMember()] public long Sumar2Numeros(long valor1, long valor2) { return valor1 + valor2; } }

Esta clase posee una funcin que retornar la suma de los dos parmetros enviados. Si registramos esta clase como cdigo JavaScript del cual se pueda crear una instancia, podremos acceder a sta como si se tratase de cdigo JavaScript.
HtmlPage.RegisterCreateableType(Sumar2, typeof(Sumar2));

En este caso, el objeto por construir desde JavaScript se llamar Sumar2 y tendr disponibles todos los mtodos de la clase creada antes. Para obtener una instancia de este objeto en JavaScript, deberemos hacer lo siguiente:
326

Silverlight 2 y JavaScript

function Sumar() { var MiControl = document.getElementById(AplicacionSilverlight); var sumar2 = MiControl.content.services.createObject(Sumar2); alert(sumar2.Sumar2Numeros(10, 20)); }

Figura 33. Al presionar el botn para sumar, obtenemos el resultado correcto.

En la siguiente figura, podemos ver que el objeto creado, si bien es consumido desde JavaScript, en el momento en que se procesa es ejecutado en Silverlight. Esto significa que no se est creando cdigo JavaScript que simule la funcionalidad creada en Silverlight, sino que se llama a la funcin en Silverlight previamente definida.

Figura 34. La ejecucin desde JavaScript dispara el cdigo en Silverlight.

RESUMEN
En este captulo hemos visto que Silverlight tiene la capacidad de salir fuera de su marco tradicional de ejecucin e interactuar con el entorno dentro del navegador, tanto con el cdigo HTML como con el cdigo JavaScript. Este ltimo es posible ejecutarlo, manipularlo y consumirlo para generar mayor interaccin con nuestro sitio web y con el usuario. Gracias a esto, Silverlight no slo otorga funcionalidad dentro de su modelo de ejecucin, sino que tambin extiende las funcionalidades circundantes dentro del navegador web.

327

 ACTIVIDADES
PREGUNTAS TERICAS
1 Qu objeto debemos usar desde Silverlight 2 para obtener informacin de la pgina HTML contenedora de la aplicacin? 2 Es posible modificar los valores de los objetos creados en el cdigo HTML desde Silverlight 2? 3 Cundo se usa el mtodo GetElementById desde Silverlight 2? 4 Cmo podemos ejecutar el envo de un formulario web desde Silverlight 2? 5 Cmo podemos lanzar una nueva ventana del navegador desde Silverlight 2? 6 Qu es una cookie? 5 Pruebe crear una aplicacin Silverlight que 7 Cmo leemos y escribimos cookies desde Silverlight 2? 8 Cmo podemos ejecutar cdigo JavaScript desde Silverlight 2? 9 Qu atributo decorativo necesitamos utilizar para que el cdigo Silverlight pueda ser ejecutado desde JavaScript? 10 Qu eventos JavaScript se disparan slo por medio de la accin del usuario? Nombre algunos de ellos. se visualice en modo de pantalla completa. 4 Con el nuevo control creado en el ejercicio anterior, utilice cookies para dirigir al usuario a la pgina que estaba viendo, en la aplicacin Silverlight, antes de cerrar la ventana del navegador. 3 Modifique el ejemplo de navegacin por marcadores para incluir un nuevo control. 2 Para conocer ms sobre el uso de reflexin sobre Microsoft .Net, ingrese en http:// msdn.microsoft.com/es-es/.

EJERCICIOS PRCTICOS
1 Visite el sitio de CodePlex (www.codeplex. com/IronPython), para informarse de cmo implementar tecnologas tales como IronPython y Silverlight 2.

328

Silverlight

Apndice

Silverlight fuera de Windows


Silverlight es una tecnologa provista y mantenida por Microsoft. Si bien esta compaa centra su desarrollo en los sistemas operativos con mayor uso en el mercado de computadoras de escritorio de la actualidad, como OS X de Apple y Windows, la comunidad tambin hace su trabajo, creando soporte para sistemas operativos como Linux y Unix.

SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com

Proyecto Moonlight Sistemas operativos Versiones de Moonlight Herramientas de desarrollo Problemas conocidos

330 330 331 331 333

APNDICE A. SILVERLIGHT FUERA DE WINDOWS

PROYECTO MOONLIGHT
Moonlight es un proyecto creado por la comunidad de desarrolladores y patrocinado por la compaa Novell. El objetivo de Moonlight es el de poder crear y ejecutar aplicaciones Silverlight bajo sistemas operativos con base Linux y Unix. De esta forma, es posible llevar el uso de esta tecnologa a la mayor gama de usuarios, sin importar su sistema operativo e, incluso, su navegador. Teniendo en cuenta que de manera nativa Silverlight es soportado por Opera, Internet Explorer y Firefox bajo Windows y OS X de Apple, con Moonlight se ampla el horizonte al ejecutar Silverlight en Linux con Firefox.

Figura 1. En la direccin www.mono-project.com/Moonlight encontramos el sitio web del proyecto Moonlight.

Sistemas operativos
Moonlight fue diseado para soportar diferentes sistemas operativos Linux, tanto para arquitecturas x86 de 32 Bits como x86-64 para 64 Bits. En la Tabla 1, podemos ver la lista de sistemas operativos y versiones de navegadores web soportados en cada caso.
ARQUITECTURA x86 (32 Bits) SISTEMA OPERATIVO SUSE Linux Enterprise Desktop 10 openSUSE 11.0 openSUSE 11.1 Ubuntu 8.04 Fedora Core 9 x86-64 (64 bits) SUSE Linux Enterprise Desktop 10 openSUSE 11.0 FIREFOX 2.0 S S S S S S No FIREFOX 3.0 S S S S S S S

Tabla 1. Sistemas operativos y navegadores web soportados por Moonlight.


330

Proyecto Moonlight

En cuanto a requerimientos, para ejecutar una aplicacin Silverlight desde Firefox, deberemos contar con 128 MB de memoria RAM, en cualquiera de las arquitecturas.

Versiones de Moonlight
En la actualidad, Moonlight cuenta con soporte total para Silverlight 1.0. La nueva versin con soporte para Silverlight 2.0 contina en desarrollo y tiene fecha de salida para septiembre de 2009. Esto puede ser un punto en contra para Moonlight y los usuarios de Linux, porque Microsoft ya cuenta con la versin 3 de Silverlight liberada. Tengamos en cuenta que la capacidad de desarrollo y conocimiento sobre la tecnologa Silverlight nace desde Microsoft, por lo que es natural pensar y esperar que la empresa est un paso adelante en la entrega de nuevas versiones y de nuevas funcionalidades para sus productos, mientras que la comunidad debe esperar la salida de estos productos y tecnologas, analizarlos, estudiarlos, para luego poder implementarlos. Este ciclo continuo de nuevas versiones y constante aprendizaje por parte de la comunidad acarrea este tipo de conflictos con las versiones, dejando a muchos usuarios desactualizados y desatendidos. De cualquier manera, la nueva versin de Moonlight pretende mostrar significantes cambios, como la inclusin de Deep Zoom, Microsoft Media Pack 2.0 para manejo de video y sonido, la posibilidad de utilizar los controles y componentes propuestos por Microsoft para Silverlight, entre otras caractersticas que lo acercan mucho ms a su versin para Windows.

Herramientas de desarrollo
Si bien el comportamiento de la librera de clases provista por Microsoft es el mismo usado por Moonlight, los creadores de ste no recomiendan el uso de Visual Studio 2008 para la creacin de aplicaciones Silverlight especficas para Linux. Esto se debe a que, al estar Moonlight en continuo desarrollo, an presenta ciertos errores, en especial para Silverlight 2, que podran causar un comportamiento no esperado dentro de sistemas operativos basados en Linux. En todo caso, si quisiramos desarrollar directamente bajo Linux, los creadores recomiendan el uso de la herramienta de desarrollo llamada MonoDevelop.

DESCARGAR MOONLIGHT
Si queremos iniciarnos en el desarrollo de Moonlight o, simplemente, visualizar aplicaciones creadas con esta tecnologa en Linux, es posible descargar el plugin de Moonlight de la siguiente pgina web: www.go-mono.com/moonlight. All tambin podemos encontrar instrucciones de instalacin y el historial de cambios de la aplicacin.

331

APNDICE A. SILVERLIGHT FUERA DE WINDOWS

Figura 2. MonoDevelop, una herramienta gratuita creada por la comunidad desarrolladora de Mono y Moonlight.

MonoDevelop es, tambin, una herramienta de uso libre y gratuito para el desarrollo con Mono, lo que quiere decir que nos proveer herramientas no slo para el desarrollo de aplicaciones Silverlight, sino que podremos crear aplicaciones web y de escritorio para Linux utilizando Microsoft .Net Framework como modelo base y C# como lenguaje de desarrollo. A la fecha, MonoDevelop se encuentra en su versin 2, y, como en toda comunidad de cdigo abierto, es posible participar en su mejora. Como ya dijimos, Moonlight es un proyecto de la comunidad para la comunidad. ste es libre y de cdigo abierto. Por tal motivo, si deseamos colaborar en su mejora contamos con la posibilidad de hacerlo. En el sitio web de Moonlight, podemos encontrar las direcciones de los servidores SVN (Subversion o repositorio de versiones), que nos darn acceso al cdigo y a cada una de las versiones histricas de estos archivos. Si no contamos con un cliente SVN o herramienta similar, existen excelentes alternativas gratuitas que hallaremos en Internet. Por ejemplo, TortoiseSVN, una de las recomendadas y usadas ampliamente en el desarrollo de software. TortoiseSVN cuenta con versiones para arquitecturas de 32 y 64 bits. No slo es til para este caso especifico, ya que podemos sacarle provecho al incluirlo en nuestros desarrollos de software, y al utilizarlo con sitios web que brindan servicios gratuitos de almacenamiento para

MONODEVELOP
Es importante recordar que MonoDevelop es una herramienta de uso libre y gratuito, con la que podremos llevar nuestras aplicaciones .Net a la plataforma Linux, rompiendo la barrera tradicional entre sistemas operativos. Podemos descargar MonoDevelop desde la siguiente direccin: http://monodevelop.com.

332

Proyecto Moonlight

desarrollo de productos de software, como Google Code (http://code.google.com/ hosting/) o Microsoft CodePlex (www.codeplex.com), sitio que podemos utilizar como repositorio de cdigo fuente. Adems, es posible encontrar grandes cantidades de cdigo de ejemplo para utilizar en nuestros proyectos.

Figura 3. TortoiseSVN es una poderosa herramienta para el manejo de archivos histricos en el desarrollo de software.

Figura 4. Google Code es un repositorio de cdigo para alojar el cdigo de nuestro proyecto y poder trabajar de forma colaborativa.

Problemas conocidos
Debido a que Moonlight se basa en el modelo de trabajo propuesto por Mono, las limitaciones de este ltimo son traspasadas tambin a Moonlight y a la ejecucin de Silverlight. Adems, por estar un paso atrs en el soporte de las versiones oficiales de Silverlight, otros problemas relacionados con la funcionalidad misma de
333

APNDICE A. SILVERLIGHT FUERA DE WINDOWS

Silverlight aparecen en Moonlight. Una de las destacadas y heredadas del modelo de trabajo Mono que sustenta Moonlight es la falta de implementacin de LinQ en su totalidad, por lo que es recomendable no utilizar este tipo de consultas integradas dentro del cdigo que realicemos bajo Linux. Por otro lado, el modelo de trabajo Mono est enfocado para soportar y simular funcionalidad presentada en Microsoft .Net Framework 2.0. Como en el transcurso del libro trabajamos con funcionalidades presentes en Microsoft .Net Framework 3.0 y 3.5, puede que la mayora del cdigo presentado deba ser adaptado a la versin 2.0 de Microsoft .Net Framework. De cualquier manera, no todo est rodeado de malas noticias, ya que la comunidad detrs de Moonlight es una comunidad activa y en constante crecimiento sta har de Moonlight un sistema cada vez ms robusto y funcional con el correr del tiempo, a medida que se sumen ms personas con espritu colaborativo que quieran apoyar el desarrollo de mejora del proyecto.

Figura 5. En el sitio web de Moonlight, se listan algunos sitios con los que se prueban las diferentes versiones de esta herramienta y su resultado al ejecutar aplicaciones Silverlight.

Como vimos, Moonlight es un gran proyecto propuesto por la comunidad desarrolladora de cdigo libre y abierto y, si bien puede estar desfasado en relacin con las nuevas versiones de Silverlight producidas por Microsoft, no deja de ser un componente que evoluciona da a da y que permite, con facilidad, mover la tecnologa Silverlight a ambientes donde no llegara por s sola. No dudemos en apoyar este tipo de emprendimientos y desarrollos que nos permiten obtener mayor cantidad y mejor calidad de productos de software.

334

Silverlight

Apndice

Silverlight 3, la nueva generacin


En el momento en que se edita este libro, Microsoft saca a la luz la versin 3 de Silverlight. Por eso, en este apartado, tocaremos los temas ms importantes que diferencian a Silverlight 2 de Silverlight 3, para as poder acoplarnos con facilidad a esta reciente tecnologa.

SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com

Silverlight 3 Nuevos controles Efectos en tres dimensiones Uso de Pixel Shader Fuera del navegador

336 336 337 338 339

APNDICE B. SILVERLIGHT 3, LA NUEVA GENERACIN

SILVERLIGHT 3
Silverlight 3 viene con grandes mejoras para el desarrollador, algo que tambin se traduce en progresos para el usuario. Mejor uso del hardware del equipo cliente, implementacin de funcionalidades de tres dimensiones, mayor soporte para formatos de video y sonido, y la posibilidad de ejecutar la aplicacin fuera del navegador son slo algunas de los nuevos adelantos. Curiosamente, el tamao del plugin para descargar por los navegadores es apenas menor que el de la versin anterior, lo que tambin nos dice que el cdigo de ste se ha optimizado de manera sustancial al incorporar mayor funcionalidad con menos lneas de cdigo por parte de su motor de ejecucin.

Nuevos controles
En esta entrega de Silverlight 3, fueron agregados nuevos controles. Muchos de stos son para satisfacer necesidades puntuales sobre carencias anteriores. A la hora de desarrollar aplicaciones, es comn encontrarse con necesidades bsicas sobre el comportamiento de los controles, por lo que, si la tecnologa no trae la solucin incluida en ella, es necesario construir lneas de cdigo con funcionalidad para subsanar este problema. Por este motivo, es comn que Microsoft, por cada entrega de nuevas tecnologas, incorpore mayores controles de aquellos que reconoce como necesarios por parte de los desarrolladores. Uno de estos controles es el campo de texto con la funcionalidad de autocompletar. Pasndole una fuente de datos cualquiera, es posible que este control muestre una lista desplegable con los elementos que coincidan con lo introducido por el usuario.
<input:AutoCompleteBox x:Name=autoCompletar IsTextCompletionEnabled=True Width=200 Height=30> </input:AutoCompleteBox>

Si tenemos cualquier fuente de datos, incluso servicios web o WCF de donde obtener esta informacin, este control nos mostrar los datos de cmo hacerlo.

ACTUALIZARSE
Para mantenerse actualizado sobre las nuevas funcionalidades incluidas en Silverlight 3, podemos ver los videos tutoriales en el sitio web oficial de Silverlight. Debemos ingresar en el siguiente sitio para visualizar estos videos: http://silverlight.net/learn/. Vale aclarar que los videos se encuentran en ingls.

336

Silverlight 3

Figura 1. Una lista desplegable basada en la seleccin del usuario.

Otros controles como el TreeView (rbol jerrquico), ValidationSummary (resumen de validaciones) o DataPager (paginador) son tambin parte del nuevo abanico de controles y componentes disponibles en esta versin.

Efectos en tres dimensiones


Silverlight 3 adiciona la caracterstica de manipular objetos bidimensionales en un espacio tridimensional. Si bien no incluye, an, el manejo de objetos tridimensionales de forma nativa, s es posible simular este comportamiento mediante un nuevo conjunto de transformaciones. Estas transformaciones son llamadas proyecciones, y trabajan manipulando el elemento dentro del espacio XYZ segn los grados de rotacin.
<Image Source=bosque_pokemon.jpg Width=400 Height=250> <Image.Projection> <PlaneProjection RotationX=50 RotationY=30 RotationZ=35> </PlaneProjection> </Image.Projection> </Image>

Veamos, en la Figura 2 de la prxima pgina, cmo la imagen transformada tiene la apariencia de estar realmente dentro de un espacio de tres dimensiones. Tambin notemos que esta transformacin genera un mejor aspecto que la que intentamos, en el captulo 4, al modificar un control DataGrid para conseguir una apariencia de tres dimensiones. En ese caso, simulbamos este aspecto, pero el plano de proyeccin no era necesariamente correcto.
337

APNDICE B. SILVERLIGHT 3, LA NUEVA GENERACIN

Figura 2. Una imagen de dos dimensiones proyectada en un plano de tres.

Este tipo de proyecciones no slo se aplica a imgenes, sino que pueden ser usadas en cualquier control provisto por Silverlight. Otros atributos presentados por el modelo de proyeccin se refieren al punto de proyeccin. As como tenamos un punto que representaba el eje de rotacin de un elemento, este punto de proyeccin sita ese eje de proyeccin tambin dentro del espacio de tres dimensiones, pudiendo modificar por completo el comportamiento y la visualizacin de los objetos.

Uso de Pixel Shader


Pixel Shader es un componente incluido en las actuales tarjetas de video presentes en los equipos hogareos. Este componente funcional permite manipular y tratar la salida del video a la pantalla, haciendo uso del procesador de la tarjeta video. Esto agiliza la puesta en escena de las imgenes, permitiendo aplicar ciertos tratamientos a stas, antes de que sean mostradas. Como esta funcionalidad est impresa en el hardware de la tarjeta, los clculos sobre las modificaciones resultan ms rpidos que los realizados por lneas de cdigo. Silverlight 3 hace uso de estas funcionalidades adicionando efectos de video que luego sern traducidos y ejecutados por el hardware del usuario.
<Image Source=bosque_pokemon.jpg Width=400 Height=250> <Image.Projection> <PlaneProjection RotationX=50 RotationY=30 RotationZ=35> </PlaneProjection> </Image.Projection> <Image.Effect> <DropShadowEffect BlurRadius=15 ShadowDepth=10> </DropShadowEffect> </Image.Effect> </Image>

338

Silverlight 3

En el caso anterior, aplicamos un efecto de sombra de manera dinmica, calculada en el momento mediante Pixel Shader. Otro efecto disponible desde Silverlight 3 es el de Blur o difuminado. Si bien estos dos los encontraremos incluidos por defecto y listos para usar, es posible, si tenemos el conocimiento, elaborar efectos propios con Pixel Shader, creando cdigo en HLSL (High Level Shader Language o lenguaje de alto nivel para Shader), compilndolo e incluyndolo en la aplicacin Silverlight.

Figura 3. Esta imagen cuenta con un clculo de sombra dinmica mediante la aplicacin de Pixel Shader

Fuera del navegador


Si bien todo el entorno de ejecucin de Silverlight se encuentra dentro del navegador, la nueva versin nos permite configurar la aplicacin fuera de l. Para esto, se requiere el consentimiento del usuario y algo de configuracin de nuestra parte. Esta caracterstica puede asestar un gran golpe a las tpicas aplicaciones de escritorio, ya que con Silverlight obtenemos gran potencial de diseo, trabajando en la Web, y adems ahora puede quedarse en el escritorio y ejecutarse desde ste. Podremos configurar estas caractersticas desde las propiedades del proyecto, como vemos en la siguiente figura:

Figura 4. Configuraciones necesarias para utilizar la aplicacin desde el escritorio.


339

APNDICE B. SILVERLIGHT 3, LA NUEVA GENERACIN

Al instalar y ejecutar la aplicacin desde el escritorio, veremos el mismo comportamiento sumando las caractersticas configuradas desde las propiedades del proyecto, como se muestra en la Figura 5 y en la Figura 6.

Figura 5. Instalacin de la aplicacin Silverlight en nuestro escritorio.

Figura 6. La aplicacin instalada, ahora puede ser ejecutada sin necesidad de contar con el navegador web.

Silverlight 3 tiene an muchas ms novedades y slo hemos visto algo superficial de todas las nuevas caractersticas que presenta. Si ya estamos desarrollando con Silverlight 2 y queremos ampliar nuestros horizontes en esta tecnologa, lo que hemos visto nos puede servir como un buen punto de partida para investigar y ahondar ms en Silverlight 3 y su nueva propuesta.

340

Silverlight

Servicios al lector
En este apartado encontraremos una lista de sitios web de alta utilidad para iniciarnos en el desarrollo de aplicaciones Silverlight, as como para obtener informacin de soporte para poder crear nuevas aplicaciones y quitar cualquier velo de duda sobre la implementacin de cdigo y la aplicacin de tcnicas novedosas relacionadas con esta tecnologa.

SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com

ndice temtico Sitios web recomendados

342 345

SERVICIOS AL LECTOR

NDICE TEMTICO
A
AJAX Almacenamiento aislado Animaciones App.Config AS ASP.net Autocompletar AutoUpgrade 15 239 19, 45, 170, 175 271 250 64, 317 336 58 Data DataContext DataGrid DatePicker DateTime 48 98 276 142 135 48, 101, 168, 183 102 67, 103, 183 Deep Zoom Depuracin Dibujar Dibujo DispatcherTimer DisplayDate DisplayMode Distorsin DLR DoubleAnimation 128 60, 139 24, 92, 222, 229 106, 123 40 318 51, 71, 74, 103, 107, 198 203 217, 225 21 173 117 46, 67 236 130 24 46, 67 GetAttribute GetElementById Flash FontFamily FontSize FontWeight Escalar Estilo Etiquetas Evento Expression Blend Cookies CookieSilver CSS Cursor 314 315 178, 317 88

D
57, 218 278 60, 68, 75, 132, 168, 231 60, 137, 147 135, 145 199, 331 62 213 46 257 143 250 167 21 171

B
Background Barras de desplazamiento Binding BlackoutDates Bool Border BorderThickness Button

C
Caja de texto Calendar Canvas CheckBox Clases Class Click ClientBin Clip CLR ColorAnimation ComboBox Componentes Context Contrasea Controles Controles

E
165 178 22, 290 72, 83, 261 26, 30

F
15 127 127 127

G
294 294

342

ndice temtico

GotFocus Grid GridSplitter Grilla GroupName

84 67, 84, 89, 279 89 47 110 LayoutUpdated LinQ ListBox LostFocus

L
84 21, 63, 74, 283 124, 252 84

H
Height Hilos HLSL Hojas de estilo HTA HTML dinmico HTML HtmlDocument HtmlPage HtmlWindow HttpHandler HyperlinkButton 39, 85, 125, 302 255 339 290, 317 83 15 290 292 300, 323 305, 310, 323 234 113 Name NavigateUri Nodo NoWrap Marcador Margin MarkerReached MediaElement MediaOpened Moonlight MouseMove

M
196 68 197 48, 188, 216 198 330 209

N
57 113 83 128

I
IHttpHandler IIS Image InkPresenter InnerHTML INPUT IntelliSense Interactividad IsEnabledChanged IsolatedStorageFile IsolatedStorageFileStream IsolatedStorageSettings 236 270 105, 114, 123, 215, 222 208, 225 295 297 61, 70 31 84 240 240 240 Param Password PasswordBox PasswordChar 290, 320 222 Pincel Pixel Shader Plantillas Plugin 84 84 PointAnimation PopupWindow OnClick Onerror OneTime OneWay OnExit OnStartup OpenFileDialog

O
321, 325 57 280 280 43 43 251, 254

P
57 131 130 131 211 338 58, 64, 178, 182 56 171 308 343

J
JavaScript Juego

K
KeyDown KeyUp

SERVICIOS AL LECTOR

Position ProgressBar Punto de interrupcin

190 148, 258 62

TextWrapping Threads TimelineMarker Timer Transformaciones

128 255 198 149, 256 45, 158, 175 158 159 218 74 280

R
RadioButton Rotacin RSS 110, 123 161 230

TransformGroup Traslacin Trazado T-SQL TwoWay

S
ScaleTransform ScriptObject ScrollViewer SDK Seguridad SelectedItem SelectionMode Servicios web SetAttribute SetProperty SetStyleAttribute ShowDialog Slider SOA SOAP Sonido Source SourceName StackPanel Storyboard Streaming String Stroke Subnodo 165 324 98 58 239, 263 119 140, 146 222 295 317 320 251 152, 191 19 265 188 50 196 95, 168, 181, 237 173, 256 21, 188, 228 281 213 83

U
Uri URL Usabilidad 225, 231, 238 230 31

V
Validadores Video VideoBrush Visual Studio 281 194 195 24

W
WCF Web.Config WebClient WebMethod Width WMA WMV WPF 21, 239, 270 234, 271 230 264 39, 85, 138, 302 188 194 16, 37, 82

X
XAML XamlReader XAP 16, 18, 21, 82, 148 238 114 230 15, 22, 82

T
Tag Text TextBlock TextBox TextBoxStyle 344 23, 82 126, 183 24, 61, 120, 126, 153, 183, 236 41, 67, 127 45

XLinQ XML

Z
Zoom 207

Sitios web recomendados

SITIOS WEB RECOMENDADOS


Memorabilia
http://memorabilia.hardrock.com Hard Rock Caf fue uno de los primeros sitios web en implementar la tecnologa Silverlight de Microsoft. Este sitio en particular presenta una coleccin completa de objetos regalados por artistas dentro de una presentacin Deep Zoom. Es recomendable ver las estampillas de cartas enviadas por Paul McCartney.

PhotoSynth
http://photosynth.net Este sitio web muestra el uso de la tecnologa PhotoSynth creada por Microsoft Research. Esta tecnologa tiene la funcin de generar espacios en tres dimensiones basados en fotografas. El software calcular los distintos puntos que componen un espacio sobre la base de todas las imgenes disponibles de ese espacio.

345

SERVICIOS AL LECTOR

Bing
www.bing.com El nuevo buscador de Microsoft incorpora funcionalidad creada con Silverlight para interactuar con distintos servicios propuestos por la compaa. Es posible guardar las bsquedas en SkyDrive, as como comentar y categorizar cada una de ellas.

Sitio oficial de Silverlight


www.silverlight.net Sitio oficial de Silverlight, donde podremos encontrar todo tipo de ejemplos sobre este software, as como herramientas y cdigo pregenerado para usar en nuestros desarrollos. No debemos olvidarnos de visitar la sala de videos educativos del sitio.

346

Sitios web recomendados

ComponentArt
www.componentart.com Compaa que provee controles y componentes de alta calidad para usar en el desarrollo de nuestras aplicaciones. Los ltimos componentes creados por esta empresa incluyen varios destinados al uso dentro de aplicaciones Silverlight (son pagos).

Infragistics
www.infragistics.com Infragistics es otra empresa que provee controles y componentes visuales para el desarrollo de aplicaciones. Presenta un gran abanico de controles para Silverlight listos para usar. De igual forma que el sitio anterior, estos componentes y controles son pagos.

347

SERVICIOS AL LECTOR

Quince
http://quince.infragistics.com Sitio propuesto por la empresa Infragistics que nos otorga una serie de patrones de diseo visual para aplicar en nuestros desarrollos. Con Quince, es posible entender cmo podemos mejorar la usabilidad de las aplicaciones desarrolladas por nosotros.

Librera MSDN
http://msdn.microsoft.com/en-us/library/cc838158(VS.95).aspx La librera MSDN para Silverlight propuesta por Microsoft es el manual de referencia a todas las clases, mtodos, funciones, controles y componentes de Silverlight. Si tenemos alguna duda sobre el desarrollo para Silverlight, es necesario acudir a este sitio.

348

Claves para comprar un libro de computacin.

Sobre el autor y la editorial

Revise que haya un cuadro "sobre el autor", en el que se informe sobre su experiencia en el tema. En cuanto a la editorial, es conveniente que sea especializada en computacin.

Preste atencin al diseo

Compruebe que el libro tenga guas visuales, explicaciones paso a paso, recuadros con informacin adicional y gran cantidad de pantallas. Su lectura ser ms gil y atractiva que la de un libro de puro texto.

Compare precios

Suele haber grandes diferencias de precio entre libros del mismo tema; si no tiene el valor en la tapa, pregunte y compare.

Desde un sitio exclusivo en la Red hasta un CD-ROM, desde un Servicio de Atencin al Lector hasta la posibilidad de leer el sumario en la Web para evaluar con tranquilidad la compra, o la presencia de adecuados ndices temticos, todo suma al valor de un buen libro.

No slo el del texto; tambin revise que las pantallas incluidas en el libro estn en el mismo idioma del programa que usted utiliza.

Est en letra pequea en las primeras pginas; si es un libro traducido, la que vale es la fecha de la edicin original.

Compra Directa!

usershop.redusers.com Visite nuestro sitio web


Utilice nuestro sitio usershop.redusers.com:
Vea informacin ms detallada sobre cada libro de este catlogo. Obtenga un captulo gratuito para evaluar la posible compra de un ejemplar. Conozca qu opinaron otros lectores. Compre los libros sin moverse de su casa y con importantes descuentos. Publique su comentario sobre el libro que ley. Mantngase informado acerca de las ltimas novedades y los prximos lanzamientos.

Tiene valores agregados?

Verifique el idioma

Revise la fecha de publicacin

Tambin puede conseguir nuestros libros en kioscos o puestos de peridicos, libreras, cadenas comerciales, supermercados y casas de computacin.

usershop.redusers.com

usershop@redusers.com I (011) 4110.8700

Adquiralo con todos los medios de pago*


Captulo Gratis Avant Premire Promocin Ofertas
(*) Slo vlido para la Repblica Argentina

LA PREPARACIN IDEAL PARA DESARROLLADOR CINCO ESTRELLAS DE MICROSOFT


sta es una obra terica y prctica para aprender a programar. Basado en el curso Desarrollador Cinco Estrellas de Microsoft, este material brinda las habilidades necesarias para iniciar el camino que nos lleve a convertirnos en desarrolladores de la plataforma .NET.

DESARROLLADORES I 400 pginas ISBN 978-987-1347-74-2

usershop.redusers.com
Adquiralo con todos los medios de pago
Captulo GRATIS Promocin Ofertas

SILVERLIGHT
CONTENIDO
1 | INTRODUCCIN A SILVERLIGHT Experiencia de usuario y portabilidad | Arquitectura de Silverlight 2 | Microsoft .NET Framework | Interfaz de usuario y presentacin | El cdigo XAML | Herramientas de desarrollo 2 | MICROSOFT EXPRESSION BLEND 2 Silverlight con Expression Blend | Explorador de soluciones | Entorno | Barra de herramientas | Crear nuestra primera aplicacin 3 | SILVERLIGHT PARA DESARROLLADORES Puesta a punto de Visual Studio 2008 | Crear la primera aplicacin | Interoperabilidad con Expression Blend 2 4 | XAML AL EXTREMO El lenguaje XAML | Declaracin de objetos | Controles y componentes | Grid | GridSplitter | Canvas | StackPanel | ScrollViewer | Border | Controles de iteracin con el usuario | Button | CheckBox | RadioButton | HyperlinkButton | Image | ComboBox | ListBox | TextBlock | TextBox | PasswordBox | DataGrid | Calendar | DatePicker | ProgressBar | Slider 5 | LUZ, CMARA, ACCIN Mover objetos | Transformaciones de traslacin, rotacin, escalar y distorsin | Animaciones | DoubleAnimation | ColorAnimation | Estilos y plantillas 6 | CERRAR EL CRCULO MediaElement | Ejecutar sonidos | Elementos con video embebido | Deep Zoom | Dibujar con InkPresenter | reas de dibujo 7 | INTERCONEXIN Ampliar las funcionalidades | Silverlight desde C# | WebClient | Enviar informacin | Capacidad de almacenamiento | OpenFileDialog | Manejo de hilos | Temporizador | Hilos y eventos | Consumir servicios desde Silverlight | Manipular datos | LinQ 8 | EL NAVEGADOR Y SU DOMINIO Conectar tecnologas | Silverlight 2 y HTML | HtmlDocument y HtmlElement | HtmlPage | HtmlWindow | Cookies | Modificar CSS | Silverlight 2 y JavaScript | Llamar funciones | Objetos para JavaScript APNDICE A | SILVERLIGHT FUERA DE WINDOWS APNDICE B | SILVERLIGHT 3, LA NUEVA GENERACIN

DESCUBRA UN NUEVO NIVEL EN EL DESARROLLO DE APLICACIONES PARA INTERNET


Desde su lanzamiento, Silverlight se convirti rpidamente en la opcin multiplataforma ideal, tanto para desarrollar aplicaciones enriquecidas e interactivas, como para generar experiencias multimedia de vanguardia. Quien consiga dominarlo podr ofrecer a sus clientes aplicaciones visualmente impresionantes, tiempos de respuesta sin comparacin y requerimientos mnimos de ancho de banda, todas ventajas acordes a los tiempos de la incipiente Web 3.0. Esta obra ofrece un acercamiento profundo y prctico a esta herramienta, y est dirigida a desarrolladores con conocimiento de Microsoft .NET Framework, que deseen profundizar en el desarrollo Web. La enorme experiencia de Matas Iacono como desarrollador en esta plataforma lo convierte en el gua ideal para aportar consejos prcticos bien fundados, ejemplos enriquecedores y cdigo optimizado para aplicar en sus propios proyectos.

redusers.com
En este sitio encontrar una gran variedad de recursos y software relacionado, que le servirn como complemento al contenido del libro. Adems, tendr la posibilidad de estar en contacto con los editores, y de participar del foro de lectores, en donde podr intercambiar opiniones y experiencias.

SILVERLIGHT
Silverlight is the cross-platform, cross-browser plug-in for rich interactive applications and cutting-edge media experiences. With advanced tips from our expert, this book provides practical, grounded advice, and rich examples, to be ready for todays challenges.

NIVEL DE USUARIO
PRINCIPIANTE INTERMEDIO AVANZADO EXPERTO

Das könnte Ihnen auch gefallen