Está en la página 1de 356

tapa Silverlight.qxp 21/09/2009 11:07 a.m.

Pgina 1

INCLUYE
SILVERLIGHT NOVEDADES DE
DESCUBRA UN NUEVO NIVEL EN EL DESARROLLO LA VERSiN 3.0
CONTENIDO DE APLICACIONES PARA INTERNET
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 redusers.com
En este sitio encontrar una gran variedad de recursos y software relacionado,
6 | CERRAR EL CRCULO que le servirn como complemento al contenido del libro. Adems, tendr la po-
MediaElement | Ejecutar sonidos | Elementos con video sibilidad de estar en contacto con los editores, y de participar del foro de lecto-
embebido | Deep Zoom | Dibujar con InkPresenter | reas
de dibujo
res, en donde podr intercambiar opiniones y experiencias.

7 | INTERCONEXIN
Ampliar las funcionalidades | Silverlight desde C# |
DESCUBRA UN NUEVO NIVEL EN EL DESARROLLO
WebClient | Enviar informacin | Capacidad de
almacenamiento | OpenFileDialog | Manejo de hilos |
DE APLICACIONES PARA INTERNET
Temporizador | Hilos y eventos | Consumir servicios desde
Silverlight | Manipular datos | LinQ
SILVERUGHT PARA DISEADORES
8 | EL NAVEGADOR Y SU DOMINIO
Conectar tecnologas | Silverlight 2 y HTML | HtmlDocument
Y DESARROLLADORES
y HtmlElement | HtmlPage | HtmlWindow | Cookies |
Modificar CSS | Silverlight 2 y JavaScript | Llamar funciones MICROSOFT EXPRESSION BLEND 2
| Objetos para JavaScript Y MICROSOFT VISUAL STUDIO 2008
APNDICE A | SILVERLIGHT FUERA DE WINDOWS
SILVERLIGHT UNQ, WCF y SERVICIOS WEB CON C#
APNDICE B | SILVERLIGHT 3, LA NUEVA GENERACIN
Silverlight is the cross-platform, cross-browser plug-in
for rich interactive applications and cutting-edge
CREACiN DE ANIMACIONES Y TCNICAS
NIVEL DE USUARIO media experiences. With advanced tips from our DE ESCRITURA PARA DISPOSITIVOS TCTILES
expert, this book provides practical, grounded advice,
PRINCIPIANTE INTERMEDIO AVANZADO EXPERTO and rich examples, to be ready for todays challenges. INTERACCiN CON JAVASCRIPT, HTML, XML y CSS por MATAS IACONO
1 ,j , "' j I I ' ,1" \ r, ' I II \l '\ j " I I

APROVECHE AL MXIMO SU POTENCIAL ILIMITADO


RT_Bombo_LIBROSilverlight.qxp 21/09/2009 17:07 Pgina RT2

CONCTESE CON LOS MEJORES


LIBROS DE COMPUTACIN
usershop.redusers.com

DESCUBRA EL POTENCIAL DE WINDOWS VISTA APRENDA A PROGRAMAR CON EL LENGUAJE MS POTENTE


MANUALES USERS I 384 pginas I ISBN 978-987-1347-40-7 DESARROLLADORES I 400 pginas I ISBN 978-987-1347-76-6

MANEJE LAS HERRAMIENTAS DE VISTA COMO UN EXPERTO DESARROLLE APLICACIONES PARA WINDOWS Y LA WEB
MANUALES USERS I 352 pginas I ISBN 978-987-663-007-8 MANUALES .CODE I 368 pginas I ISBN 978-987-1347-32-2
00_Silverlight.qxp 9/30/09 1:16 PM Page 1

DESCUBRA UN NUEVO NIVEL EN EL DESARROLLO


DE APLICACIONES PARA INTERNET
00_Silverlight.qxp 9/30/09 1:16 PM Page 2

TTULO: SILVERLIGHT

AUTOR: Matas Iacono

COLECCIN: Manuales USERS

FORMATO: 17 x 24 cm

PGINAS: 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 to-
tal, el almacenamiento, el alquiler, la transmisin o la transformacin de este libro, en
cualquier forma o por cualquier medio, sea electrnico o mecnico, mediante foto-
copias, 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 responsa-
bilidad alguna por cualquier consecuencia derivada de la fabricacin, funcionamien-
to 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 due-
os. 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
00_Silverlight.qxp 9/30/09 1:16 PM Page 3
00_Silverlight.qxp 9/30/09 1:16 PM Page 4

PRELIMINARES

Matas Iacono
Ingeniero de sistemas, Microsoft Most Valuable Professional en
ASP.net, Orador Regional para INETA Latam, Scrum Master cer-
tificado 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 Mo-
torola Argentina y es profesor en la Universidad Tecnolgica Na-
cional 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 ha-
berme facilitado material y a Lucas Ontivero, de Motorola Ar-
gentina, por su crtica aguda, que me ayud con el contenido pro-
puesto en el libro.

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

4
00_Silverlight.qxp 9/30/09 1:16 PM Page 5

Prlogo

PRLOGO
Si hay algo a lo que le debemos la actual difusin de la tecnologa informtica, tan-
to dentro del hogar como de las oficinas, es a la continua evolucin de las interfa-
ces grficas de usuarios (GUI). Gracias a ellas, personas de todas las edades y pro-
fesiones, en todo el mundo, pueden interactuar con equipos de computacin para
fines tan diversos como entretenerse, obtener informacin, realizar clculos y co-
municarse, entre un sinnmero de otras posibilidades.
Es seguro que tanto la constante innovacin en el desarrollo de las interfaces gr-
ficas 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 rela-
cionan mediante el uso de la tecnologa.
Mientras que la Web seguir siendo el mbito de comunicacin del futuro, es de es-
perar que los requerimientos de interactividad entre mquinas y humanos se vuel-
van an ms sofisticados y exigentes. Ante esto, Microsoft desarroll Silverlight, una
nueva apuesta para el desarrollo de elementos de grficos de interaccin con los usua-
rios 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, curiosida-
des, 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

5
00_Silverlight.qxp 9/30/09 1:16 PM Page 6

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 tipos de proyectos disponibles desde este


INTRODUCCIN A SILVERLIGHT 2 entorno de desarrollo.
Para conocer Silverlight desde sus comienzos,
en este captulo describiremos Captulo 4
su arquitectura. Hablaremos de las diferencias XAML AL EXTREMO
entre aplicaciones tradicionales y las nuevas Cada uno de los controles y componentes
aplicaciones visuales, y conoceremos la lista proporcionados por Silverlight,
de herramientas necesarias para poder su funcionalidad, eventos, mtodos
desarrollar aplicaciones Silverlight. y funciones, sern vistos en este captulo.
Cada uno de estos elementos ser descripto
Captulo 2 con profundidad, generando cdigo
MICROSOFT EXPRESSION BLEND 2 de ejemplo por cada uno de ellos.
En este captulo nos enfocaremos Este captulo representa una excelente gua
en Microsoft Expression Blend 2 como de referencia sobre todos los componentes
herramienta de desarrollo para Silverlight, disponibles en Silverlight.
orientada a diseadores visuales
y a diagramadores de aplicaciones. Daremos Captulo 5
un paseo por la interfaz de Microsoft LUZ, CMARA, ACCIN
Expression Blend 2 y crearemos nuestra Gran parte de las prestaciones otorgadas
primera aplicacin Silverlight. Este captulo por Silverlight incluyen la posibilidad
ayudar a los diseadores y desarrolladores de mover objetos dentro de nuestra aplicacin.
a entender cada uno de estos mundos. En este captulo veremos cmo manipular esta
caracterstica, ya que se explicarn
Captulo 3 los distintos modelos disponibles para
EL MEJOR TRABAJO, CON LA MEJOR animaciones y transformaciones dentro
HERRAMIENTA de las aplicaciones Silverlight.
Luego de enfocarnos en el diseador visual,
centraremos la atencin de este captulo Captulo 6
en el desarrollador. Para esto, veremos CERRAR EL CRCULO
qu posibilidades nos ofrece Microsoft Visual Silverlight tambin otorga mucho potencial
Studio 2008 para desarrollar aplicaciones con el manejo de imgenes, video y sonido.
Silverlight, los controles y componentes En este captulo hablaremos de ciertas
propuestos, su interfaz visual y los diferentes caractersticas relacionadas con actividades

6
00_Silverlight.qxp 9/30/09 1:16 PM Page 7

El libro de un vistazo

como consumir videos, mostrar imgenes Apndice A


o tocar sonidos dentro de las aplicaciones. SILVERLIGHT FUERA DE WINDOWS
Tambin hablaremos de Deep Zoom Gracias a MoonLight, Silverlight puede salir
y sus caractersticas, as como del dibujo de Windows y trabajar en sistemas
a mano alzada con InkPresenter. operativos basados en Linux y Unix.
Hablaremos del proyecto MoonLight,
Captulo 7 sus caractersticas, limitaciones y el futuro
INTERCONEXIN de Silverlight como tecnologa fuera
Este captulo ofrece funcionalidades de su ambiente nativo. Adems, se presentan
altamente valiosas. Crearemos un juego algunas herramientas gratuitas y de cdigo
desde cdigo C# y un lector de RSS, libre que nos ayudarn en el desarrollo,
usaremos almacenamiento aislado para tanto para Windows como para Linux.
guardar informacin en el cliente, crearemos
aplicaciones para subir archivos al servidor Apndice B
y culminaremos con la implementacin SILVERLIGHT 3, LA NUEVA GENERACIN
de la ltima tecnologa de interoperabilidad Daremos un vistazo al producto recientemente
propuesta por Microsoft al conectar Silverlight lanzado por Microsoft. Silverlight 3 trae
con Windows Communication Foundation. consigo valiosas mejoras al modelo
ya planteado, las que enumeraremos para
Captulo 8 ganar conocimiento adicional por sobre
EL NAVEGADOR Y SU DOMINIO lo ya aprendido durante todo el libro.
Silverlight se ejecuta dentro de una pgina
HTML manejada por el navegador web. Servicios al lector
Por tal motivo, posee gran potencial En esta ltima seccin, encontraremos
de interaccin con el cliente. En este captulo un ndice que nos ayudar a buscar de forma
veremos cmo Silverlight puede manipular rpida los trminos ms importantes de esta
HTML as como intercambiar informacin obra. Adems, veremos un listado de sitios
con JavaScript. Adems, conoceremos cmo de inters para ampliar nuestros
JavaScript es capaz de consumir servicios conocimientos y mantenernos al tanto
generados desde Silverlight. 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

7
00_Silverlight.qxp 9/30/09 1:16 PM Page 8
00_Silverlight.qxp 9/30/09 1:16 PM Page 9

Contenido

CONTENIDO

Sobre el autor 4 Captulo 3


Prlogo 5 EL MEJOR TRABAJO,
El libro de un vistazo 6 CON LA MEJOR HERRAMIENTA
Informacin complementaria 7 Silverlight para desarrolladores 56
Introduccin 12 Puesta a punto de Visual Studio 2008 56
Silverlight 2 con Visual Studio 59
Captulo 1 Crear la primera aplicacin
INTRODUCCIN A SILVERLIGHT 2 con Visual Studio 2008 63
Iniciarse en el mundo de Silverlight 2 14
Navegar hacia el mundo
de Silverlight 2 14
La experiencia de usuario
y la portabilidad 16
Arquitectura de Silverlight 2 19
Microsoft .Net Framework 20
Interfaz de usuario y presentacin 21
El cdigo XAML 22
Herramientas de desarrollo
para Silverlight 2 24 Interoperabilidad con
Resumen 27 Expression Blend 2 76
Actividades 28 Resumen 79
Actividades 80
Captulo 2
MICROSOFT EXPRESSION BLEND 2 Captulo 4
Un paseo por Expression Blend 2 30 XAML AL EXTREMO
Silverlight 2 con Expression Blend 2 30 El lenguaje XAML 82
Unir los extremos 32 Qu es XAML? 82
Un recorrido por Expression Blend 2 37 Declaracin de objetos 82
Explorador de soluciones 38 Controles y componentes 83
Pgina inicial de Silverlight 2 39 Controles contenedores y agrupadores 84
La pgina App.xaml 40 Control Grid 84
El entorno de Expression Blend 2 43 Control GridSplitter 89
La barra de herramientas 46 Control Canvas 92
Crear nuestra primera aplicacin Control StackPanel 95
con Expression Blend 2 48 Control ScrollViewer 98
Resumen 53 Control Border 101
Actividades 54 Controles de interaccin con el usuario 103

9
00_Silverlight.qxp 9/30/09 1:16 PM Page 10

PRELIMINARES

Control Button 103 ColorAnimation 173


Control CheckBox 106 Animaciones y transformaciones 175
Control RadioButton 110 Estilos y plantillas 178
Control HyperlinkButton 113 Estilos 178
Control Image 114 Plantillas 182
Control ComboBox 117 Resumen 185
Control ListBox 124 Actividades 186
Control TextBlock 126
Control TextBox 127
Control PasswordBox 130
Control DataGrid 132
Control Calendar 139
Control DatePicker 147
Control ProgressBar 148
Control Slider 152
Resumen 153
Actividades 154

Captulo 6
CERRAR EL CRCULO
MediaElement 188
Ejecutar sonidos 188
Video 194
Elementos con video embebido 195
Marcadores de video 196
Deep Zoom 199
Crear el primer Deep Zoom 200
Incluir Deep Zoom en Silverlight 203
Captulo 5 Dibujar con InkPresenter 208
LUZ, CMARA, ACCIN Dibujar en forma manual 212
Mover objetos 156 Dibujar sobre otros elementos 215
Transformaciones 158 InkPresenter y reas de dibujo 217
Transformacin de traslacin 159 Resumen 219
Transformacin de rotacin 161 Actividades 220
Transformacin escalar 165
Transformacin de distorsin 167 Captulo 7
Aplicar todas las transformaciones 168 INTERCONEXIN
Animaciones 170 Ampliar las funcionalidades 222
DoubleAnimation 171 Silverlight desde C# 222

10
00_Silverlight.qxp 9/30/09 1:16 PM Page 11

Contenido

WebClient 230 Cookies 316


Enviar informacin 233 Modificar CSS 320
Almacenamiento aislado 239 Silverlight 2 y JavaScript 323
Implementar el almacenamiento Llamar funciones 325
aislado 240 Objetos Silverlight
Capacidad de almacenamiento 245 para JavaScript 327
Almacenar configuraciones 247 Resumen 347
OpenFileDialog 251 Actividades 348
Manejo de hilos 255
El concepto de hilos 256 Apndice A
Temporizador 257 SILVERLIGHT FUERA
Personalizar los hilos 259 DE WINDOWS
Hilos y eventos 261 Proyecto Moonlight 330
Consumir servicios Sistemas operativos 330
desde Silverlight 263 Versiones de Moonlight 331
Crear un servicio WCF 270 Herramientas de desarrollo 331
Manipular datos 275 Problemas conocidos 333
Enlazado de datos 276
LinQ 283
Resumen 287
Actividades 288

Captulo 8
EL NAVEGADOR Y SU DOMINIO

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

11
00_Silverlight.qxp 9/30/09 1:16 PM Page 12

PRELIMINARES

INTRODUCCIN
Este libro est orientado a desarrolladores de software, y diseadores visuales y gr-
ficos que deseen expandir su rea de conocimiento de desarrollo hacia el ambiente
web. Un lector con nociones iniciales podr ver, durante los captulos, una evolu-
cin que le dar la oportunidad de aprender sin necesidad de saberes previos sobre
la tecnologa propuesta, Silverlight, mientras que aquel lector con experiencia po-
dr encontrar en estas pginas una gua fundamental para aprender, con agilidad,
conceptos sobre esta tecnologa de Microsoft. Sin embargo, es necesario, para am-
bos 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 superfi-
cie 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 desa-
rrollo bajo esta tecnologa, tanto para diseadores como para desarrolladores, gene-
ramos 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 tec-
nologa 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 tiem-
po 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 in-
troducir 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
01_Silverlight.qxp 9/30/09 1:20 PM Page 13

Silverlight Captulo 1
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 14
Navegar hacia el mundo
de Silverlight 2 14
La experiencia de usuario
y la portabilidad 16
Arquitectura de Silverlight 2 19
Microsoft .Net Framework 20
Interfaz de usuario
y presentacin 21
El cdigo XAML 22
Herramientas de desarrollo
para Silverlight 2 24
Resumen 27
SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com Actividades 28
01_Silverlight.qxp 9/30/09 1:20 PM Page 14

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 si-
guen buscando mejores formas y herramientas para trabajar en este fascinante mun-
do. 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 desarro-
llo 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 imge-
nes 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 es-
critorio. Los cambios radicales en las tasas de transferencias de datos, as como
en las capacidades de los equipos que servan esta informacin, tambin acom-
paaron dichos acontecimientos. Por supuesto, esta evolucin no slo fue de capa-
cidades de hardware y prestaciones hacia el usuario. Al mismo tiempo, estuvo acom-
paada por software, lenguajes de programacin y herramientas de desarrollo que,
en conjunto, ayudaran a amortiguar la curva de complejidad sobre las necesida-
des crecientes que tenan los sistemas. En definitiva, existan mayores requeri-
mientos 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 herra-
mientas 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 docu-
mentos, redes sociales e interconexin de servicios, entre otros, debemos enten-
der 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 mu-
cho ms requeridas por aquellos que se ven involucrados en el desarrollo web. De-
bido 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 do-
minio 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
01_Silverlight.qxp 9/30/09 1:20 PM Page 15

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 pa-
ra 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 co-
nocimiento 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 lengua-
jes tan populares como Borland C# Builder y Delphi, tambin de Borland. De es-
ta 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, ex-
tendiendo el concepto de HTML dinmico y A.J.A.X. (Asynchronous JavaScript and
XML o, en castellano, JavaScript asncrono y XML). Tambin puede consumir ser-
vicios web o cualquier elemento con la capacidad de retornar XML, al mismo tiempo
que puede ser programado o desarrollado mediante aquel lenguaje que usamos to-
dos 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
Windows
Web Forms Web Services
Visual Studio .NET

Forms
Mobile Internet Toolkit

ADO .NET y XML

Librera de clases base

Common Language Runtime

Sistema Operativo

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
01_Silverlight.qxp 9/30/09 1:20 PM Page 16

1. INTRODUCCIN A SILVERLIGHT 2

La experiencia de usuario y la portabilidad


Antes de la aparicin de Microsoft .Net Framework, construir una aplicacin de soft-
ware 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 pro-
gramacin trajera consigo. El diseo, entonces, quedaba encapsulado dentro del cdi-
go 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 implemen-
tada 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 ne-
gocio) nunca quedara del todo igual, castigando la experiencia del usuario que se ha-
ba 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 am-
bientes 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 es-
quema XML para la confeccin y manipulacin de interfaces de usuarios: ya no
aparecan los tpicos botones y cajas de texto rgidas comunes en cualquier aplica-
cin 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 lengua-
jes de programacin y arquitectura.

16
01_Silverlight.qxp 9/30/09 1:20 PM Page 17

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 mis-
mas 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. Pen-
semos 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 den-
tro 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 Mi-
crosoft. 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 apren-
der un nuevo lenguaje para desarrollar en Microsoft .Net Framework.

17
01_Silverlight.qxp 9/30/09 1:20 PM Page 18

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 pro-
ducto 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
Navegadores web de escritorio

CSS/HTML XAML

JavaScript/AJAX
Framework .Net
ASP.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 Fra-
mework 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
01_Silverlight.qxp 9/30/09 1:20 PM Page 19

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 es-
critorio y, por el otro, la portabilidad entre plataformas y la rapidez de la actuali-
zacin 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, posibi-
litar 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 pun-
tos ganados con la utilizacin de XAML y Silverlight.

Arquitectura de Silverlight 2
Al comienzo de nuestro recorrido, nombramos algunas de las caractersticas de Sil-
verlight que, al mismo tiempo, definen su planteo arquitectnico. Dijimos que
Silverlight est enfocado a la Web y que es ejecutado por el navegador web. Es-
to se consigue gracias a un plugin o aditivo que har las veces de gestor o in-
trprete. 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), re-
des, 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 carac-
tersticas 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 acos-
tumbrado 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
01_Silverlight.qxp 9/30/09 1:20 PM Page 20

1. INTRODUCCIN A SILVERLIGHT 2

.NET para Silverlight


Data WPF WCF

LINQ Controls REST POX Librera para


XLINQ Data Binding RSS/ATOM JSON Microsoft
XML Layout SOAP AJAX
Editing

DLR BCC

Iron Python Generics


Iron Ruby Collections Motor
Jscript Cryptography JavaScript
Threading

Motor de ejecucin CLR

XAML

Centro de interfaz Perifricos DRM


grfica
Keyboard Media
Vector Text
Mouse
Animation Images
Ink

Multimedia

VC1
WMA
MP3
Centro de presentacin

Manejo de navegador
Integrado Integrado Servicio Instalador
con la red con DOM de aplicaciones

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
01_Silverlight.qxp 9/30/09 1:20 PM Page 21

Iniciarse en el mundo de Silverlight 2

LinQ y XLinQ: soporte especializado para llevar a cabo el manejo de colec-


ciones 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 Frame-
work, que nos ofrece soporte para el manejo de cadenas de texto, expresiones regu-
lares, 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 pa-
ra lenguajes de programacin como JavaScript, Iron Phyton e Iron Ruby.
Almacenamiento aislado: permite generar sectores de almacenamiento de archi-
vos 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 pre-
sentacin 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 co-


mo 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 fa-
cilita 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 con-
feccin de las interfaces. stas son creadas sobre la base de XML.

Como pudimos ver hasta aqu, Silverlight no es un simple visualizador de ani-


maciones, 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 uti-
lizados, por lo general, en el desarrollo de aplicaciones de escritorio y web, ade-
ms, 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 nave-
gador web, sin estar atado a un sistema operativo ni a un navegador especfico.

21
01_Silverlight.qxp 9/30/09 1:20 PM Page 22

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 exactamen-
te. 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 (ba-
se 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 orien-
tada a objetos y puede absorber todos los beneficios inherentes a este modelo de programacin.

22
01_Silverlight.qxp 9/30/09 1:20 PM Page 23

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 nom-
bre ms los caracteres </, lo que especificar la finalizacin del tag. En el ejemplo, tam-
bin podemos notar cmo un elemento puede contener otros elementos, as como atri-
butos 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 defi-
nidas 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
01_Silverlight.qxp 9/30/09 1:20 PM Page 24

1. INTRODUCCIN A SILVERLIGHT 2

El ejemplo nos sirve, al mismo tiempo, para mostrar otros atributos importantes den-
tro 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 con-
trol, 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 vi-
sual. Con este atributo, podremos cambiar el texto representado al principio en tiem-
po 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 con-
troles 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 poten-
ciamiento visual en interfaces de usuario, sera muy interesante contar con herramien-
tas 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 fuen-
tes 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 ele-
mentos 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 sub-
conjunto 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
01_Silverlight.qxp 9/30/09 1:20 PM Page 25

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 mencio-


nada, 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 po-
der 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 ade-
lante, es posible construirlos por nuestra cuenta desde cero, toda la lgica de funcio-
nalidad ya se encuentra contenida y probada en ellos. Esto nos ahorra tiempo de tra-
bajo 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 aba-
nico 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 con-
junto 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
01_Silverlight.qxp 9/30/09 1:20 PM Page 26

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 in-
gls. 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 ace-
lerar el desarrollo de componentes Silverlight. Veremos ms a fondo las cualida-
des 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 Ex-
pression Blend 2 se compenetran de tal forma que, por lo comn, nos veremos
creando cdigo en la primera herramienta, abriendo y editando el mismo pro-
yecto 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 for-
ma 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 con-
tar 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
01_Silverlight.qxp 9/30/09 1:20 PM Page 27

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 con-
tar con las herramientas instaladas en nuestro equipo antes de continuar con los
siguientes captulos. Es posible tambin realizar los ejemplos con las versiones gra-
tuitas 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
01_Silverlight.qxp 9/30/09 1:20 PM Page 28

 ACTIVIDADES

PREGUNTAS TERICAS EJERCICIOS PRCTICOS

1 En qu modelo se basa el cdigo XAML pa- 1 Dirjase al sitio web de la W3C (www.
ra representar los elementos de la interfaz? w3.org/XML) para aprender ms sobre
XML.
2 Subconjunto de qu otro modelo de desa-
rrollo visual para Windows podramos con- 2 Para introducirse mejor en el mundo de
siderar a Silverlight? Silverlight, intente ampliar el ejemplo pro-
puesto en este captulo, modificando el
3 Qu versin de Microsoft .Net Framework tipo de fuente y el color de fondo de la apli-
necesitamos, como mnimo, para trabajar cacin creada.
con Silverlight 2.0?
3 Para conocer ms sobre desarrollo con
4 Qu sistemas operativos y navegadores Microsoft .Net, tome el curso gratuito del
web soportan la ejecucin de Silverlight 2.0? Desarrollador 5 Estrellas desde el sitio
web de Microsoft. Este curso ayuda a en-
5 Qu herramienta resulta ideal para desa- tender trminos utilizados en este libro. La
rrolladores, que les permita potenciar el URL es www.mslatam.com/latam/msdn/
desarrollo de aplicaciones Silverlight 2.0? comunidad/dce2005.

6 Los diseadores visuales cuentan con al- 4 Instale Microsoft Expression Blend 2 y
guna herramienta de software que los ayu- djelo listo para trabajar en el siguiente
de a crear contenido para Silverlight 2.0? captulo.

7 Es necesario instalar algn aditamento en 5 Una vez instalados Visual Studio 2008 y
la herramienta de desarrollo? Microsoft Expression Blend 2, ingrese en
www.silverlight.net, el sitio oficial de
8 Silverlight 2.0 provee algn conjunto de Silverlight, descargue los ejemplos y
componentes listos para usar? analcelos. Esto ayuda a entender con
mayor facilidad esta tecnologa.
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?

28
02_Silverlight.qxp 9/30/09 1:23 PM Page 29

Silverlight Captulo 2
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 Un paseo por Expression


Blend 2 30
que abordaremos en este captulo. Silverlight 2 con Expression
Blend 2 30
Unir los extremos 32
Un recorrido por Expression
Blend 2 37
Explorador de soluciones 38
Pgina inicial de Silverlight 2 39
La pgina App.xaml 40
El entorno de Expression
Blend 2 43
La barra de herramientas 46
Crear nuestra primera
aplicacin con Expression
Blend 2 48
Resumen 53
SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com Actividades 54
02_Silverlight.qxp 9/30/09 1:23 PM Page 30

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 he-
rramientas 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. Es-
to 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 reso-
lucin 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 compu-
tadoras, 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 mis-
mas, 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 momen-
to 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 po-


ne 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 tecnolo-
gas multitctiles en sistemas operativos, o de captura de movimientos en consolas de juegos.

30
02_Silverlight.qxp 9/30/09 1:23 PM Page 31

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 vi-
suales 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 desarro-
llos 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, co-
mo 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 nues-
tros desarrollos. El xito de nuestro producto no est marcado slo por las lneas de cdigo,
la usabilidad es un aspecto muy importante.

31
02_Silverlight.qxp 9/30/09 1:23 PM Page 32

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 vi-
suales 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 herramien-
tas que stos utilizan. Cuando en un proyecto de software es necesaria la interven-
cin 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 reali-
zar 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, pe-
ro 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 im-
genes o un esquema que mostrar lo pretendido de manera visual para la aplica-
cin 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
02_Silverlight.qxp 9/30/09 1:23 PM Page 33

Un paseo por Expression Blend 2

<td>
[...41 lneas eliminadas ...]
<td colspan=2><img name=Untitled1_r4_c1 src=images/Untitled-
1_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
02_Silverlight.qxp 9/30/09 1:23 PM Page 34

2. MICROSOFT EXPRESSION BLEND 2

El problema es claro: estas herramientas hacen las veces de traductores, pero no de ge-
neradores. Traducen lo que el diseador quiso decir a algo que el desarrollador pueda
entender, pero, en este proceso de traduccin, las herramientas no traducen funciona-
lidad, 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 herra-
mienta de las que est acostumbrado a usar. Sin embargo, a medida que diagrama y
disea los contenidos visuales, sta generar funcionalidad lista para ser implementa-
da 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
02_Silverlight.qxp 9/30/09 1:23 PM Page 35

Un paseo por Expression Blend 2

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

El diseador ver, en lugar del cdigo anterior, un modelo como el que se mues-
tra 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 en-
focarse directamente en la solucin del problema. A modo de ejemplo, en las si-
guientes lneas de cdigo vemos cmo el desarrollador agrega algunas lneas de
cdigo C# en la clase asociada al cdigo XAML para generar funcionalidad so-
bre 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
02_Silverlight.qxp 9/30/09 1:23 PM Page 36

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 com-
patibles entre s, para que ninguno de los profesionales involucrados tenga la ne-
cesidad 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 exclusiva-
mente 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
02_Silverlight.qxp 9/30/09 1:23 PM Page 37

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 en-
capsulamiento de elementos XAML y cdigo de programacin para su posterior
reutilizacin en aplicaciones WPF. Debemos optar por esta opcin cuando quere-
mos 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 si-


milar 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
02_Silverlight.qxp 9/30/09 1:23 PM Page 38

2. MICROSOFT EXPRESSION BLEND 2

Adems de poder indicar el nombre del proyecto que vamos a crear y la ubica-
cin fsica que tendr, es posible seleccionar el lenguaje de programacin con el
cual preferimos trabajar. Vale aclarar que, para poder conseguir esta lista, es ne-
cesario 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 im-
portante 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, ade-
ms, 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 pro-
yecto Silverlight, lo podamos hacer con mayor facilidad desde estas herramientas.

38
02_Silverlight.qxp 9/30/09 1:23 PM Page 39

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 apli-
cacin en s misma, sino como un componente que puede ser incrustado o con-
sumido 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 System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;

RRR DIMENSIONES DE SILVERLIGHT

Es posible hacer que nuestro control Silverlight se adapte a la superficie que lo contiene. Si co-
locamos 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
02_Silverlight.qxp 9/30/09 1:23 PM Page 40

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 c-
digo 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
02_Silverlight.qxp 9/30/09 1:23 PM Page 41

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 en-
cuentre 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
02_Silverlight.qxp 9/30/09 1:23 PM Page 42

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 vi-
da 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
02_Silverlight.qxp 9/30/09 1:23 PM Page 43

Un paseo por Expression Blend 2

El primer mtodo, constructor de esta clase, se encarga de enlazar eventos inhe-


rentes al comportamiento de nuestra aplicacin. El mtodo OnStartup se ejecutar
al inicio de la aplicacin, en este caso, podramos colocar cdigo en l para con-
seguir algn comportamiento necesario al momento de inicializarse nuestra apli-
cacin. Por ejemplo, podramos necesitar inicializar objetos o conectarnos a un
servicio web, entre otras posibilidades. En el mismo caso, el evento OnExit ser dis-
parado 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 lien-
zo, podremos arrojar y ordenar todos los controles incluidos en Silverlight, as co-
mo 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
02_Silverlight.qxp 9/30/09 1:23 PM Page 44

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 con-
taremos 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 venta-
ja 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
02_Silverlight.qxp 9/30/09 1:23 PM Page 45

Un paseo por Expression Blend 2

elementos sobre alguno de los controles existentes para aplicar las configuracio-
nes 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 en-
cuentra 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 aplica-
cin. 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 p-
gina 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 rpi-
da. 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
02_Silverlight.qxp 9/30/09 1:23 PM Page 46

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, principal-


mente, en agrupar otros controles Silverlight, aunque tambin se encargan de
ordenar, dentro de la superficie de dibujo, la disposicin de esos elementos. As,

46
02_Silverlight.qxp 9/30/09 1:23 PM Page 47

Un paseo por Expression Blend 2

podemos encontrar grillas, donde se definirn filas y columnas (agregando den-


tro de cada celda distintos controles y componentes) o elementos de barras de
desplazamiento para colocar contenido que exceda los lmites de ancho o alto de-
finidos 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, lis-
tas 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 di-
recta. 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 dis-
ponibles y agregarlos a nuestra coleccin de controles, como se muestra a continuacin.

47
02_Silverlight.qxp 9/30/09 1:23 PM Page 48

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 apa-
riencia 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 modi-
ficar toda su implementacin de servicios para los usuarios fue Terra, al cambiar su utilizacin
de Adobe Flash por Silverlight.

48
02_Silverlight.qxp 9/30/09 1:23 PM Page 49

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 den-
tro 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, presio-
nando dos veces con el puntero del ratn sobre el control, o mediante sus propie-
dades. El resultado debera ser similar al mostrado en la siguiente figura.

49
02_Silverlight.qxp 9/30/09 1:23 PM Page 50

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 con-
trol 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 compo-
nente MediaElement de manera especial. Una vez que hemos seleccionado el video
en cuestin, presionamos la tecla F5 para inicializar la aplicacin. Esta accin de-
ber iniciar un explorador de Internet y desplegar la aplicacin creada. Podremos
notar que el video se reproduce con normalidad, pero los botones creados para ca-
da 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 se-
r posible iniciarlo, pausarlo o detenerlo. Podemos asignarle el nombre al control
seleccionndolo y agregndole el mismo que tiene en la lista de propiedades o me-
diante 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 signifi-
cado en ingls). Debido a que el trmino, con el tiempo, mut, tendremos ms chances de hallar
informacin mediante este ltimo nombre.

50
02_Silverlight.qxp 9/30/09 1:23 PM Page 51

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#, necesita-
remos 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 cuen-
ta. 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 expe-
rimentados conocedores del lenguaje de programacin utilizado. De cualquier ma-
nera, 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. Gra-
cias a este servidor, no dependeremos de grandes infraestructuras para desplegar y ejecutar
nuestros proyectos cada vez que necesitemos validar lo que estemos desarrollando.

51
02_Silverlight.qxp 9/30/09 1:23 PM Page 52

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. Pa-
ra 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 cual-
quier 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 System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightApplication2
{
public partial class Page : UserControl

{
public Page()
{

52
02_Silverlight.qxp 9/30/09 1:23 PM Page 53

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 pue-
de 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
02_Silverlight.qxp 9/30/09 1:23 PM Page 54

 ACTIVIDADES

PREGUNTAS TERICAS EJERCICIOS PRCTICOS

1 Cul es, en el desarrollo web, el principal 1 Ingrese y navegue por Quince (http://
problema con el que se encuentra un desa- quince.infragistics.com), el sitio web de
rrollador al recibir el trabajo del diseador Infragistics dedicado a la mejora de las in-
para ser implementado? terfaces visuales.

2 Por qu es importante poner esfuerzo en 2 Dirjase al sitio web oficial de Silverlight


el rea de experiencia visual del usuario? (http://silverlight.net) para ver ms ejem-
plos sobre esta plataforma.
3 Qu herramientas intentan unir el diseo
y el desarrollo de software? 3 Intente crear un visor de videos por Inter-
net, ejecutando la aplicacin creada me-
4 Por qu es importante la creacin de proto- diante el uso de IIS (Internet Information
tipos visuales en el desarrollo de software? Services).

5 Podemos encontrar todos los controles y 4 Ingrese en www.microsoft.com/surface,


componentes HTML representados en Sil- el sitio web de Microsoft Surface, para ver
verlight con XAML? buenos ejemplos de interfaces visuales y
su aplicacin en soluciones de software.
6 Qu tipos de proyectos es posible crear
con Expression Blend 2? 5 Visite el sitio de experiencia para el usua-
rio de Microsoft (www.microsoft.com/
7 Es necesario instalar algn programa adi- design) para maximizar el conocimiento
cional para poder desarrollar aplicaciones sobre posibilidades involucradas en esta
Silverlight 2 con Expression Blend 2? rea de la ingeniera de software.

8 Si queremos ver todos los controles de Ex-


pression 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?

54
03_Silverlight.qxp 9/30/09 1:29 PM Page 55

Silverlight Captulo 3
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


Silverlight para desarrolladores 56
con la que podremos obtener cdigo Puesta a punto de Visual
Studio 2008 56
Silverlight 2 con Visual Studio 59
de extrema calidad.
Crear la primera aplicacin
con Visual Studio 2008 63
Interoperabilidad con
Expression Blend 2 76
Resumen 79
SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com Actividades 80
03_Silverlight.qxp 9/30/09 1:29 PM Page 56

3. EL MEJOR TRABAJO, CON LA MEJOR HERRAMIENTA

SILVERLIGHT PARA DESARROLLADORES


En este punto, ya hemos pasado por los conceptos iniciales de Silverlight y recorri-
mos 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 instala-
cin descargando los componentes desde la pgina de Microsoft. El motivo de es-
ta 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 dis-
ponible para su descarga, pero si elegimos una incorrecta nos retrasar en nuestro
trabajo, as como tambin podemos encontrarnos con algn funcionamiento ines-
perado 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
03_Silverlight.qxp 9/30/09 1:29 PM Page 57

Silverlight para desarrolladores

debe instalar todo usuario que quiera ver las aplicaciones Silverlight desde el na-
vegador. 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 equi-
pos 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 ver-
siones, adems de indicarle al navegador de dnde obtener esta versin:

<object data=data:application/x-silverlight, type=application/x-


silverlight-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=text-
decoration: 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, ve-
mos 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 aplica-
cin 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 apli-
cacin. 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 con-
trario, Silverlight no slo cumple con esta caracterstica, sino que extiende el desarrollo de apli-
caciones profesionales al ambiente web con contenido dinmico. Podemos usar Silverlight, en
especial, cuando tengamos que resolver problemas complejos desde la Web.

57
03_Silverlight.qxp 9/30/09 1:29 PM Page 58

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 tie-
ne 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 s-
lo 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 ele-
mento 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 re-
comendable usar mquinas virtuales para instalar versiones beta.

58
03_Silverlight.qxp 9/30/09 1:29 PM Page 59

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
03_Silverlight.qxp 9/30/09 1:29 PM Page 60

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 se-
r 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 de-
sarrollo ideal, porque tiene en cuenta los roles involucrados y preocupados por satis-
facer 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 relaciona-
do 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 mos-
trados 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
03_Silverlight.qxp 9/30/09 1:29 PM Page 61

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 c-


digo 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
03_Silverlight.qxp 9/30/09 1:29 PM Page 62

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, don-
de 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
03_Silverlight.qxp 9/30/09 1:29 PM Page 63

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 desa-
rrollo de software convencional, sino que, adems, todas sus prestaciones pue-
den 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 ac-
tuarn 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 podre-
mos ver las plantillas disponibles. En este caso, seleccionaremos la plantilla Aplicacin
de Silverlight para poder probar directamente nuestro proyecto; para ello, utilizaremos

63
03_Silverlight.qxp 9/30/09 1:29 PM Page 64

3. EL MEJOR TRABAJO, CON LA MEJOR HERRAMIENTA

alguna aplicacin ASP.net existente o crearemos una pgina de prueba para nues-
tra 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 dere-
cha 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 permi-
tir 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 ejecuta-
ble. Tiempo de ejecucin alude, en cambio, al momento en que nuestro cdigo se ejecuta.

64
03_Silverlight.qxp 9/30/09 1:29 PM Page 65

Silverlight para desarrolladores

Generacin automtica de una pgina: en este caso, Visual Studio no crear nin-
guna pgina ni proyecto adicional a la solucin y slo veremos el proyecto
Silverlight en el cual trabajaremos. Cuando intentemos depurar la aplicacin Sil-
verlight, 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 previamen-
te creado, podremos usar esta opcin para vincular el proyecto Silverlight con
aqul y depurarlo basado en esta implementacin existente. Deberemos selec-
cionar 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 in-


teractuar 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 insta-
lado 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
03_Silverlight.qxp 9/30/09 1:29 PM Page 66

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 po-
dremos 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 no-
sotros 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 ver-
siones previas a la ltima versin del Framework.

66
03_Silverlight.qxp 9/30/09 1:29 PM Page 67

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 posi-
bilidad de activar la bsqueda. Esto podemos conseguirlo mediante un compo-
nente 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 especfica-
mente 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 con-
tendr la grilla, pudiendo definir elementos <ColumnDefinition> dentro de sta, los
que especificarn cada una de las columnas por visualizar. La grilla definida slo ser-
vir 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 bo-
tn, los que ubicaremos en la primera fila, y primera y segunda columna de nues-
tra 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
03_Silverlight.qxp 9/30/09 1:29 PM Page 68

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 mis-


mo control y no, como podramos estar acostumbrados en HTML o lenguajes simila-
res, 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 con-
trol. 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 agre-
gar al control mrgenes en pixeles para que no cubra la totalidad de la celda (es posi-
ble asignarles mrgenes izquierdos, superiores, derechos e inferiores, en ese orden, se-
parados 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 ca-
pacidades 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 re-
ferencia es System.Windows.Controls.Data y es necesaria para utilizar aquellos compo-
nentes 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
03_Silverlight.qxp 9/30/09 1:29 PM Page 69

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 posicio-
nar este componente en una de las celdas de la grilla, aunque en este caso apa-
rece 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
03_Silverlight.qxp 9/30/09 1:29 PM Page 70

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 infor-
macin 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 iden-
tificador 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
03_Silverlight.qxp 9/30/09 1:29 PM Page 71

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
03_Silverlight.qxp 9/30/09 1:29 PM Page 72

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 da-
tos sobre los cuales trabajaremos. Para esto, crearemos una lista genrica de pro-
ductos y la cargaremos con datos suficientes para poder hacer bsquedas sobre
ellos. La carga de la lista podremos dispararla desde una funcin privada que se-
r llamada una nica vez cuando la aplicacin se cargue en primera instancia. Es-
to podemos lograrlo llamando el llenado de la lista desde la funcin Page en nues-
tro cdigo similar al siguiente:

RRR EVENTOS

Todos los controles en Silverlight poseen una serie de eventos. Estos eventos representan si-
mulaciones 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 reaccio-
nes, las llamamos eventos.

72
03_Silverlight.qxp 9/30/09 1:29 PM Page 73

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
03_Silverlight.qxp 9/30/09 1:29 PM Page 74

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 descrip-
cin 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
03_Silverlight.qxp 9/30/09 1:29 PM Page 75

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 pa-
ra 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 re-
dimensionar 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
03_Silverlight.qxp 9/30/09 1:29 PM Page 76

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 cdi-
go 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. S-
lo 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 expe-
riencia, podra transformarse en una situacin un tanto frustrante. Por ello, es reco-
mendable 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
03_Silverlight.qxp 9/30/09 1:29 PM Page 77

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 so-
lucin y, a la izquierda, la lista de controles presentes en el proyecto. Editar las propie-
dades 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
03_Silverlight.qxp 9/30/09 1:29 PM Page 78

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 vol-
veremos 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 recar-
gada, depuramos el cdigo presionando la tecla F5. Luego, si inspeccionamos el cdi-
go 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
03_Silverlight.qxp 9/30/09 1:29 PM Page 79

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
03_Silverlight.qxp 9/30/09 1:29 PM Page 80

 ACTIVIDADES

PREGUNTAS TERICAS EJERCICIOS PRCTICOS

1 Por qu es importante colocar la versin 1 Para saber ms sobre LinQ, ingrese en el


correcta de Silverlight en la declaracin sitio de MSDN (http://msdn.microsoft.
HTML del componente? com/es-es) y busque esta tecnologa.

2 Qu es un SDK? 2 Para poner en prctica LinQ, trate de mo-


dificar el ejemplo presentado en este cap-
3 Es necesario instalar algn aditamento tulo incorporando el precio dentro de los
para Visual Studio 2008 antes de desarro- parmetros del filtro de bsqueda.
llar con Silverlight 2?
3 Intente cambiar los colores utilizados pa-
4 Cul es la diferencia entre Expression ra representar los elementos en el control
Blend 2 y Visual Studio 2008? DataGrid y, as, obtener un nuevo aspecto
en la aplicacin.
5 Es posible adicionar referencias a servi-
cios web en un proyecto Silverlight 2? 4 Si el cdigo HTML presentado en este ca-
ptulo le result extrao, visite el sitio web
6 Cmo se denomina el mecanismo que de la W3C para aprender ms sobre esta
proporciona ayuda en el momento de la es- tecnologa: www.w3.org/html.
critura de cdigo?
5 Revise la documentacin sobre servicios
7 Contamos, en Visual Studio 2008, con so- web en la direccin http://msdn.microsoft.
porte para escritura de cdigo XAML? com/es-es para saber ms sobre este tema.

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 propie-


dad AutoGenerateColumns y no usarla en el
control DataGrid?

80
04_Silverlight.qxp 9/30/09 1:31 PM Page 81

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

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 mover-
nos 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 ca-
da uno de los elementos representados con XAML provistos por Silverlight, sus
propiedades y sus usos elementales desde C#. Esta parte del libro puede ser con-
siderada 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 dife-
rentes 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 ele-
mentos 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 mis-
mos elementos en aplicaciones de escritorio. XAML, entonces, une bajo el mismo
lenguaje declarativo la posibilidad de utilizar una nica interfaz grfica en diferen-
tes 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 aten-
cin 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 cual-
quier 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 83

Controles y componentes

caracteres </, por lo dems, el nombre del objeto de apertura y su sintaxis son idn-
ticos. 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 mis-
mos 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 adicio-
nar, adems, versatilidad y simpleza en el momento de tener que crear compo-
nentes 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 con-
troles 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 re-
gulares podan ser ejecutados en Windows sin la necesidad explcita de un navegador web.

83
04_Silverlight.qxp 9/30/09 1:31 PM Page 84

4. XAML AL EXTREMO

GotFocus: este evento se disparar cuando el control tome el foco de la accin. Pue-
de 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 cam-
bio de tamao del control, este evento ser disparado.
LostFocus: sta es la accin opuesta a GotFocus. En el momento en que el con-
trol 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 imple-
mentacin 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 desarrollado-
res 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 85

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 en-
tre 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 nues-
tro 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 in-
cluirse 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 colo-
car tantos <ColumnDefinition> como columnas queramos tener en nuestra grilla. Al
finalizar la lista, cerramos el tag por medio de </Grid.ColumnDefinitions>. En el c-
digo 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 86

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 repre-
sentado por un * (asterisco); este signo representa un comodn y significa que la
columna ocupar los pixeles indicados anteriormente ms todos los que se en-
cuentran libres, no definidos por las dems columnas.
Si tenemos una grilla que ocupa 400 pixeles de ancho, y contamos con una su-
ma total de columnas, de acuerdo con el ejemplo anterior, de 130 pixeles, la se-
gunda 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 dife-
rentes entornos con distintas resoluciones de pantalla, lo que hara que la pgi-
na 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 confi-
guraciones 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 87

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 espe-
cificamos 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 es-
tos 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 88

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 con-
trol de grilla, pudiendo elegir entre Arrow (flecha), Eraser (borrador), Hand (ma-
no), 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 duran-
te determinado tiempo sobre el control de grilla. En el siguiente cdigo, se apli-
can 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 89

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 supe-
rior, 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 especifi-


car la distribucin de la grilla dentro del contenedor principal. Podremos usar las
propiedades Left (izquierda), Center (centro), Right (derecha) y Stretch (estirado) pa-
ra 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
GridSplitter no es un contenedor por s solo, sino que se conjuga conel control
Grid para poder manipular las columnas de este control y desplazarlaslibremen-
te. Para poder utilizarlo, en primer lugar, deberemos configurar una grilla que

89
04_Silverlight.qxp 9/30/09 1:31 PM Page 90

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 posiciona-


r. 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 im-
plementacin 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 atri-
buto 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 91

Controles y componentes

los valores mnimos y mximos, en este orden, a los que podr encogerse o esti-
rarse 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 92

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 conte-
nedor, 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 93

Controles y componentes

El objetivo del control Canvas es el de poder agrupar, de forma simple, otros ele-
mentos 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 transfor-


maciones que pueda sufrir un control. En este caso, mediante el uso del tag
<SkewTransform>, se especifican los valores numricos de la distorsin. Hablare-
mos 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 94

4. XAML AL EXTREMO

ser especificados en el control contenido y configuran la posicin en pixeles con-


tando desde la esquina superior izquierda del control Canvas. En el siguiente
ejemplo, el control del botn se posicionar a 106 pixeles desde la izquierda ex-
trema 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 95

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 con-
troles 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 96

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
04_Silverlight.qxp 9/30/09 1:31 PM Page 97

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 con-
troles 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 lis-
ta de controles contenidos por el StackPanel. Podemos ver el resultado de pulsar
varias veces el botn en la figura de la siguiente pgina.

97
04_Silverlight.qxp 9/30/09 1:31 PM Page 98

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 conte-
nido. 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 com-
pleto 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 sobre-
pasa 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 conteni-
do creado dentro del control ScrollViewer que exceda el tamao del contenedor
tampoco ser visible. Esta propiedad es til cuando queramos sincronizar dos

98
04_Silverlight.qxp 9/30/09 1:31 PM Page 99

Controles y componentes

ScrollViewer, 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, in-
cluso, 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>

La siguiente figura, muestra cmo se han implementado dos controles ScrollViewer,


los cuales han sido sincronizados para que, sobre la base del contenido del segun-
do, 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 con-
trol 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 100

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 di-
nmica para ser agregados a los controles StackPanel que estn contenidos por
los ScrollViewer. En el caso del control ScrollViewer, el evento actualizar la po-
sicin 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 101

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 extre-
madamente 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 mane-
ra, este control posee otros atributos que resultan tiles. Es posible asignarle un
grosor a cada lado del borde, as como crear esquinas redondeadas. A continua-
cin podemos ver la declaracin de un control Border:

101
04_Silverlight.qxp 9/30/09 1:31 PM Page 102

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 in-
ferior, en ese orden, separado por comas. El atributo CornerRadius especifica el radio
numrico de curvatura de las esquinas pudiendo determinar los valores para la esqui-
na 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 valo-
res por aquellos que sean convenientes para la aplicacin que estemos realizando.

102
04_Silverlight.qxp 9/30/09 1:31 PM Page 103

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 ac-
ciones 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 en-
contramos en todas las interfaces visuales. Posee como objetivo principal el de
disparar acciones por parte del usuario. Su declaracin es intuitiva, como po-
demos 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 con-
trol. 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 104

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
04_Silverlight.qxp 9/30/09 1:31 PM Page 105

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 con-


troles. 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 ha-
cer 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 con-
tenedor 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 106

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, tpica-
mente, un cuadrado donde el usuario puede marcar o desmarcar la casilla. Para de-
clarar 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 107

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
04_Silverlight.qxp 9/30/09 1:31 PM Page 108

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
04_Silverlight.qxp 9/30/09 1:31 PM Page 109

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
04_Silverlight.qxp 9/30/09 1:31 PM Page 110

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 continua-
cin, 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 con-
troles 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 con-
veniente. 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, debere-
mos 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 me-
diante el atributo GroupName. Si colocamos los dos controles dentro del mismo grupo,
obtendremos el resultado de la figura en la pgina siguiente.

110
04_Silverlight.qxp 9/30/09 1:31 PM Page 111

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 con-
troles 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 112

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 ma-
nera 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 verifi-


cado 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 re-
lacionados 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 113

Controles y componentes

consideremos que no vamos a tener disponible el evento Indeterminate, as co-


mo 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 apli-
cacin 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 adon-
de 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 in-


corporacin 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 114

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 pa-
ra desplegar imgenes en nuestras aplicaciones Silverlight, este control nos per-
mite 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 deba-
jo, 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 ta-
mao y, por ende, se deber descargar un archivo mayor en el cliente, que har
ms lenta la ejecucin inicial de la aplicacin.

114
04_Silverlight.qxp 9/30/09 1:31 PM Page 115

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 im-
genes 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, podre-


mos visualizarla dentro del control Image. Por el contrario, colocando la direc-
cin 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 116

4. XAML AL EXTREMO

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

En el cdigo anterior, hemos colocado dos controles Image, uno que utiliza una ima-
gen 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 con-
trol 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 cau-
sar la deformacin de la imagen.
Uniform: al igual que Fill, esta propiedad rellenar todo el contenedor con la ima-
gen, 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 117

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/wp-
content/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 con-
troles 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 118

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
04_Silverlight.qxp 9/30/09 1:31 PM Page 119

Controles y componentes

Una vez seleccionado un tem de la lista, es posible saber cul de los elementos lista-
dos 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, prime-
ro deberemos asignarle un nombre al control ComboBox ya que, de esta forma, lo ac-
cederemos 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 seleccio-
nado. 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 reali-
zamos 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 120

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 ejem-
plo anterior, es posible adicionar nuevos elementos desde nuestro cdigo. De la mis-
ma 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 sm-
bolo 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 121

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. Es-
ta 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 ele-
mentos, pudiendo manipularlos como vemos en la siguiente figura.

121
04_Silverlight.qxp 9/30/09 1:31 PM Page 122

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 cap-
turar determinadas acciones del usuario y disparar cdigo C#. Algunos de los prin-
cipales 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 lis-
ta, ste pasa a ser el elemento seleccionado, cambiando de estado la seleccin, as
como los ndices utilizados. Este evento es til cuando necesitamos cargar ele-
mentos 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 123

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/wp-
content/themes/redusers/images/logo.jpg/>
</ComboBox>

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

123
04_Silverlight.qxp 9/30/09 1:31 PM Page 124

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 se-
leccionado, presentando el mismo comportamiento que otros elementos, con la dife-
rencia 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 con-
trol 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 desplega-

124
04_Silverlight.qxp 9/30/09 1:31 PM Page 125

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 po-


sible 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/wp-
content/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 usa-
do 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 126

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 se-
leccionado, cargar nuevos elementos e interactuar con los eventos resulta similar. ni-
camente 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 senci-
llo 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 tex-
tos. 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 ma-


nipular la informacin desplegada por este control mediante el atributo Text (texto),
configurndolo en el cdigo XAML o mediante cdigo de forma dinmica. El acce-
so 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 pro-


piedad Text en nuestro cdigo, el mismo que usaremos para asignar o recolectar valo-
res 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 ta-
mao 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 127

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 atri-
butos son utilizados para configurar el tipo de fuente, su tamao y sus modificado-
res 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 de-
sarrollo 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 128

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 ma-
yor a ms de una lnea de texto, es posible usar el atributo TextWrapping para que, cuan-
do 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 flu-
jo normal y los caracteres ms antiguos escritos desaparecern del rango visual, tenien-
do 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 des-
plazamiento 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 129

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 re-
fleje 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 par-
te inferior aplica el atributo TextWrapping con el valor NoWrap, que al utilizarlo en com-
binacin con el atributo HorizontalScrollBarVisibility mostrar adems una barra de
desplazamiento en la parte inferior del control TextBox, esperando que el usuario pre-
sione 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 130

4. XAML AL EXTREMO

retornos de carro y asignarlos al control. En el cdigo siguiente, se utilizan los carac-


teres 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 destaca-
do 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 ve-
ces 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
PasswordBox es un control que extiende la funcionalidad del control TextBox con el
objetivo de brindarnos la posibilidad de manipular contraseas en nuestras aplica-
ciones. El control PasswordBox est diseado para representar todos los caracteres
introducidos por el usuario por medio de una mscara, ocultando lo que ste es-
criba y mostrando cada carcter introducido por medio de un punto de color negro.

130
04_Silverlight.qxp 9/30/09 1:31 PM Page 131

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 conti-
nuacin, 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 asig-


nacin 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 carc-
ter, 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 tradicio-
nales, como se observa en la siguiente figura.

Figura 35. Signos de resta en lugar


de crculos en el patrn del control PasswordBox.

131
04_Silverlight.qxp 9/30/09 1:31 PM Page 132

4. XAML AL EXTREMO

El control PasswordBox tambin posee eventos comunes utilizados por todos los con-
troles, 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 con-


sola 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 usua-
rio 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=clr-
namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data

132
04_Silverlight.qxp 9/30/09 1:31 PM Page 133

Controles y componentes

ste es el motivo por el cual usamos <data:DataGrid> para declarar el control en nues-
tro 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 co-
lumnas permiten personalizar por completo cada columna y adaptarla a nuestras ne-
cesidades. 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 134

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 colum-


nas 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 de-
finido por la plantilla.
<data:DataGridTemplateColumn.CellTemplate>: este tag es el que representa el con-
tenido 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 fuen-
te de datos y lo asignarn al atributo del control contenido por la plantilla. El nom-
bre 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; \ pa-
ra agregar una comilla simple.

134
04_Silverlight.qxp 9/30/09 1:31 PM Page 135

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
04_Silverlight.qxp 9/30/09 1:31 PM Page 136

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 con-


trol 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 confi-
gurar 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 re-
petirn, y la informacin no ser consistente.

136
04_Silverlight.qxp 9/30/09 1:31 PM Page 137

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, tam-
bin 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 co-
lumna 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 138

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 nece-
sario 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, de-
beremos 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 co-
lumna 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 co-
mo 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 139

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 necesi-
tamos representar la misma fecha en diferentes idiomas. Para darnos una idea
mediante un ejemplo simple, el patrn DD/MM/YYYY (da, mes, ao), utiliza-
do 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 am-
bientes de aplicaciones orientadas a la Web, debido a que stas pueden ser acce-
didas 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 con-


troles en la cabecera de nuestro archivo XAML. Esto indica que el control Calendar

139
04_Silverlight.qxp 9/30/09 1:31 PM Page 140

4. XAML AL EXTREMO

tambin se encuentra incluido en la referencia System.Windows.Controls de las li-


breras de clases de Microsoft .Net para Silverlight.

<UserControl xmlns:basics=clr-
namespace:System.Windows.Controls;assembly=System.Windows.Controls

El control Calendar posee varios atributos importantes que hacen a su configu-


racin, 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 selec-
cionado, permitiendo desplazarse de mes en mes y seleccionar uno o ms das.
Year (ao): los elementos seleccionables del calendario sern los meses del ao ele-
gido, pero no se pueden seleccionar das.
Decade (dcada): muestra el calendario en formato de aos, desplegando un conjun-
to 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 c-
mo el usuario podr seleccionar una fecha en el control Calendar. Este atributo
puede tomar los valores que se listan a continuacin:

140
04_Silverlight.qxp 9/30/09 1:31 PM Page 141

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, pe-
ro no podr concatenarlas con otros rangos o fechas individuales.
MultiRange: esta seleccin de mltiples rangos de fechas permite al usuario selec-
cionar rangos de fechas en intervalos. El usuario puede usar la tecla CTRL y el bo-
tn 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), pudien-
do 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 apli-
ca 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 ne-
cesiten mostrar das no laborales, fechas disponibles para la seleccin o fechas ya

141
04_Silverlight.qxp 9/30/09 1:31 PM Page 142

4. XAML AL EXTREMO

seleccionadas que no deban ser utilizadas por el usuario. Para lograr esto, debe-
remos 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 143

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 deter-
minado. Esto es til si necesitamos mostrarle al usuario una fecha especfica dife-
rente 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 s-
te 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 no-
vedades 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 144

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 ante-
rior 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 se-


gn lo que establezcamos desde nuestro cdigo C#. Para esto, debemos usar las pro-
piedades 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 co-
lumnas, 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 145

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
04_Silverlight.qxp 9/30/09 1:31 PM Page 146

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 seleccio-
nadas. 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 especi-
ficar 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 147

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 con-
trol 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 seleccio-
nado, 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 nu-
mrico (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 aplica-
ciones que puedan ser consumidas desde diferentes ubicaciones en el mundo. Ms informacin
en http://msdn.microsoft.com/es-es/.

147
04_Silverlight.qxp 9/30/09 1:31 PM Page 148

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 pue-
de 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 des-
plazar 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 mos-
trar con informacin de progreso inicializada.

148
04_Silverlight.qxp 9/30/09 1:31 PM Page 149

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 asig-
nar, en tiempo de ejecucin, valores al control ProgressBar para que ste mues-
tre 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 con-
trol 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 150

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 incre-


mentado en 1; esta accin se repite hasta que el valor actual de la barra de pro-
greso 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 151

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 ima-
gen como elemento de progreso y no un elemento de color plano. Si agregamos
un objeto del tipo <ImageBrush> dentro del tag <ProgressBar.Foreground>, cam-
biamos 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/wp-
content/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
04_Silverlight.qxp 9/30/09 1:31 PM Page 152

4. XAML AL EXTREMO

Control Slider
Slider es un control conocido por los desarrolladores de aplicaciones de escritorio. Pue-
de 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 m-


nimo 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 equi-
valente 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, es-
ta accin har que el acumulador salte segn el valor especificado en esta propiedad.
Orientation: el control Slider puede visualizarse de dos formas, de manera horizon-
tal 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
04_Silverlight.qxp 9/30/09 1:31 PM Page 153

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, utiliza-
remos lo que hemos visto aqu.

153
04_Silverlight.qxp 9/30/09 1:31 PM Page 154

 ACTIVIDADES

PREGUNTAS TERICAS EJERCICIOS PRCTICOS

1 XAML puede ser interpretado por siste- 1 Cree dos grupos de controles RadioButton.
mas no Microsoft? Intente que cada grupo trabaje de forma
independiente haciendo que la eleccin de
2 Cul es el problema principal entre las in- un control en un grupo no afecte el ele-
terfaces para distintas plataformas? mento seleccionado en el segundo grupo.

3 Cmo ayuda el cdigo XAML en la posibi- 2 Los controles pueden ser creados desde
lidad de transportar las interfaces entre cdigo XAML. Intente crear un conjunto de
distintas plataformas? controles, pero desde cdigo C#.

4 Cuntas maneras de cerrar elementos 3 Habiendo agregado diferentes elementos


XAML existen? dentro de un control contenedor, recorra
cada uno de los elementos contenidos y
5 En qu categoras podemos agrupar los modifique sus valores desde cdigo C#.
controles XAML?
4 Ingrese en el sitio web de UXity (www.
6 Es posible tener ms de un control conte- uxity.com) para obtener ejemplos y mate-
nedor como raz del documento XAML? rial sobre Silverlight en castellano.

7 Es posible que el usuario desplace las co- 5 Transforme un control HyperlinkButton pa-
lumnas y filas de un control Grid sin nece- ra que ste sea una imagen y no un texto.
sidad de generar cdigo?

8 Se pueden crear nuevos controles me-


diante la conjuncin de dos o ms contro-
les XAML?

9 Qu contiene un archivo con extensin XAP?

10 Qu atributo en los controles contenedo-


res de texto deberemos usar para obtener
el valor introducido por el usuario?

154
05_Silverlight.qxp 9/30/09 1:32 PM Page 155

Silverlight Captulo 5
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 Mover objetos 156


Transformaciones 158
agregar el factor dinmico a nuestras Transformacin de traslacin 159
Transformacin de rotacin 161
Transformacin escalar 165
aplicaciones, mediante el uso
Transformacin de distorsin 167
Aplicar todas
de animaciones y comportamientos. las transformaciones 168
Animaciones 170
DoubleAnimation 171
ColorAnimation 173
Animaciones
y transformaciones 175
Estilos y plantillas 178
Estilos 178
Plantillas 182
Resumen 185
SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com Actividades 186
05_Silverlight.qxp 9/30/09 1:32 PM Page 156

5. LUZ, CMARA, ACCIN

MOVER OBJETOS
En los captulos anteriores, hemos usado Silverlight para desplegar informacin des-
de 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 pa-
ra la interfaz de la mejor forma posible. Y cuando hacemos referencia a la mejor for-
ma posible, en realidad queremos decir que, muchas veces, las aplicaciones tratan de
ocupar por completo cualquier espacio disponible de la superficie de la interfaz, co-
locando 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 infor-
macin en general, cada vez ms las aplicaciones de software necesitan mostrar ma-
yor 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 boto-
nes 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 im-
portantes 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 com-
plejidad 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 apli-


caciones, as como tambin es posible optimizar el espacio de nuestra aplicacin

156
05_Silverlight.qxp 9/30/09 1:32 PM Page 157

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 man-
tener este pensamiento en el momento de realizar el diseo de aplicaciones. De cual-
quier 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 di-
ferentes controles mientras ejecutamos nuestra aplicacin. Durante este captulo,
hablaremos de las caractersticas provistas por Silverlight para poder mejorar las in-
terfaces 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 ven-
tanas o elementos que obstruyan la visin de datos importantes.

157
05_Silverlight.qxp 9/30/09 1:32 PM Page 158

5. LUZ, CMARA, ACCIN

Transformaciones
Las transformaciones son uno de los modificadores de objetos disponibles en Sil-
verlight. Con ellas, es posible cambiar la apariencia y el comportamiento de los con-
troles y componentes de la interfaz. Es posible rotarlos, escalarlos, distorsionarlos,
modificar su posicin relativa a un punto, as como invertir su posicin vertical u ho-
rizontal. 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 otor-
ga la libertad suficiente para amoldar controles tpicamente horizontales y verti-
cales, como botones y grillas de datos, entre otros, en posiciones no tradicionales.
Transformacin escalar: una transformacin escalar hace referencia a la posibi-
lidad 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 di-
mensiones 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 agrupa-
dor 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
05_Silverlight.qxp 9/30/09 1:32 PM Page 159

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 com-
paracin 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 transforma-
cin 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 enor-
memente 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 con-
troles 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
05_Silverlight.qxp 9/30/09 1:32 PM Page 160

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 obte-


nidas 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 po-
sicionado en la primera columna y la primera fila de acuerdo con los atributos

160
05_Silverlight.qxp 9/30/09 1:32 PM Page 161

Mover objetos

Grid.Column y Grid.Row, debido a la transformacin aplicada, ste se encuentra des-


plazado 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.

<RotateTransform> posee dos atributos adicionales que resultan tiles para espe-
cificar 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

161
05_Silverlight.qxp 9/30/09 1:32 PM Page 162

5. LUZ, CMARA, ACCIN

0.5 (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 mis-
mo 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.

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
05_Silverlight.qxp 9/30/09 1:32 PM Page 163

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 necesita-
mos 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 rota-
cin, 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 compo-
nentes 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
05_Silverlight.qxp 9/30/09 1:32 PM Page 164

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 sobrepa-

164
05_Silverlight.qxp 9/30/09 1:32 PM Page 165

Mover objetos

sen los lmites del objeto por rotar. De esta manera, conseguiremos que el eje de ro-
tacin quede fuera del objeto. Esto har que el punto de rotacin marque la posi-
bilidad 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 di-
mensiones a un eje XY. En la figura que vemos a continuacin, podemos apre-
ciar 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 trans-
formacin. 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
05_Silverlight.qxp 9/30/09 1:32 PM Page 166

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/>

ScaleX y ScaleY utilizan un valor numrico que representa el porcentaje de creci-


miento que recibir el objeto. En el ejemplo, utilizamos el valor 1.3, que represen-
ta 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 es-
to, vemos que este rectngulo crece hasta cubrir el rectngulo original, y lo hace
desde su centro hacia las cuatro direcciones del eje XY.

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

166
05_Silverlight.qxp 9/30/09 1:32 PM Page 167

Mover objetos

Transformacin de distorsin
Esta ltima transformacin modifica la apariencia del objeto aplicando ngulos de
torsin. 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 ex-
presado, 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 atri-
butos, 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 ti-
les, 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
05_Silverlight.qxp 9/30/09 1:32 PM Page 168

5. LUZ, CMARA, ACCIN

Aplicar todas las transformaciones


Como mencionamos, es posible aplicar ms de una transformacin a nuestros ob-
jetos, incluso, se pueden aplicar estas transformaciones a los controles para entrada
de datos, as como para aquellos que despliegan la informacin. Para poner en prc-
tica esto, extenderemos un poco el ejemplo creado en el captulo 3, modificando la
apariencia del control DataGrid, adems de agregar algunos otros elementos llama-
tivos 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 redondea-
das, aplicndole un color degradado. Estos controles, finalmente, se encuentran den-
tro 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
05_Silverlight.qxp 9/30/09 1:32 PM Page 169

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
05_Silverlight.qxp 9/30/09 1:32 PM Page 170

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 tex-
to 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 ele-
mentos 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
05_Silverlight.qxp 9/30/09 1:32 PM Page 171

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 ani-
mado. Pero adems, renace el problema de elementos guionados, que nos llevan
a pensar en todas las posibles alternativas que los elementos de nuestra aplica-
cin podran tener. Por el contrario, Silverlight utiliza para las animaciones el
mismo modelo que hemos visto en las transformaciones. Esto significa que po-
dremos animar los distintos elementos de nuestra aplicacin en tiempo de eje-
cucin, 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 canti-
dad 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 valo-


res 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 re-
presentarse en hexadecimal.
PointAnimation: esta animacin tiene la capacidad de modificar valores en propieda-
des que trabajen con puntos. Este modelo de animacin est fuertemente relaciona-
do 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 especi-
ficado por el atributo Duration (duracin). Este ltimo atributo es representado por
los valores correspondientes a horas, minutos y segundos (hh:mm:ss). Para el ejem-
plo, 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
05_Silverlight.qxp 9/30/09 1:32 PM Page 172

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
05_Silverlight.qxp 9/30/09 1:32 PM Page 173

Mover objetos

El siguiente tag es el <Storyboard>. Este tag agrupar en un conjunto todas las ani-
maciones 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 conjun-
to. 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, res-
pectivamente. 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 ini-
ciar. 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
ColorAnimation es necesaria para animaciones que modifiquen el color de los obje-
tos. Posee iguales atributos que los presentados en la animacin del tipo DoubleAnimation
y, para usarla, deberemos declararla como sigue:

<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
05_Silverlight.qxp 9/30/09 1:32 PM Page 174

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 atri-
buto 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 ani-
macin, 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
05_Silverlight.qxp 9/30/09 1:32 PM Page 175

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 ani-
macin, 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 nor-
mal. 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 ra-
pidez 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 va-
lor 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 transfor-
maciones 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
05_Silverlight.qxp 9/30/09 1:33 PM Page 176

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
05_Silverlight.qxp 9/30/09 1:33 PM Page 177

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 ani-
mar esta curva en tiempo de ejecucin para lograr efectos de ondas.

177
05_Silverlight.qxp 9/30/09 1:33 PM Page 178

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, pe-
ro existirn muchas ocasiones en las que deberemos adaptar estos elementos a nuestros
diseos, y modificar las propiedades visuales de los componentes. Para lograr esto, so-
lemos 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. Ima-
ginemos que nuestra aplicacin cuenta con veinte botones y que, despus de haber mo-
dificado 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, debe-
mos 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 es-
t 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. Pa-
ra 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
05_Silverlight.qxp 9/30/09 1:33 PM Page 179

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, po-


dremos 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. Consumi-
remos 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 gene-
rar 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 cual-
quier manera, uno de los destacados es el sitio oficial de Silverlight, hasta el que podemos na-
vegar para descargar excelentes ejemplos. La direccin es http://silverlight.net.

179
05_Silverlight.qxp 9/30/09 1:33 PM Page 180

5. LUZ, CMARA, ACCIN

Los estilos se aplican a cada una de las propiedades del objeto que queremos confi-
gurar. 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, debe-
remos 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 den-
tro del tag <Application>, es posible reutilizarlos de forma global, aunque tambin

180
05_Silverlight.qxp 9/30/09 1:33 PM Page 181

Mover objetos

pueden reducir el alcance de los estilos limitndolos al control en s o a un con-


junto 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> co-
mo 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
05_Silverlight.qxp 9/30/09 1:33 PM Page 182

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, podre-
mos crear uno nuevo. Pensemos en la capacidad de un botn de disparar un even-
to 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 con-
trol 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
05_Silverlight.qxp 9/30/09 1:33 PM Page 183

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 de-
finir el nuevo elemento. Primero el uso del control Border usado para definir el con-
torno 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 va-
lor {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 atribu-
to 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 deshabili-
tado, el control se muestra con otro color. Esto se debe a que, en su interior, estos con-
troles 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 ani-


maciones 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
05_Silverlight.qxp 9/30/09 1:33 PM Page 184

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 to-
dos los estados por los cuales reaccionar el control.

184
05_Silverlight.qxp 9/30/09 1:33 PM Page 185

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 as-
pecto que nosotros queramos, sino que, adems, es posible manipular los estados por
los cuales pasar nuestro control, pudiendo modificar su presentacin y comporta-
miento 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, transformacio-
nes 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 ca-
ptulo, nos introduciremos otro poco en caractersticas visuales como las DeepZoom, y nos
acercaremos ms an a los cdigos C# y JavaScript.

185
05_Silverlight.qxp 9/30/09 1:33 PM Page 186

 ACTIVIDADES

PREGUNTAS TERICAS EJERCICIOS PRCTICOS

1 Cuntos tipos de transformaciones pode- 1 Intente crear una animacin, utilizando


mos encontrar en Silverlight 2? ColorAnimation, para modificar el color de
fondo de un control en el momento en el
2 Si queremos especificar una transforma- que el ratn se posicione sobre l.
cin, qu tag XAML debemos usar dentro
del objeto que va a ser modificado? 2 Busque en Internet informacin sobre ani-
maciones cuadro a cuadro con Silverlight 2.
3 Qu parmetros son necesarios para apli-
car una transformacin de traslacin? 3 Busque animaciones xaml en http://msdn.
microsoft.com/es-es para aprender ms
4 Cul es la unidad utilizada en una trans- sobre transformaciones y animaciones con
formacin de rotacin? Silverlight 2.

5 Si necesitamos rotar un objeto mediante 4 Ingrese en http://msdn.microsoft.com/


una transformacin de rotacin, siempre es-es y busque animaciones 3D avanzadas
debemos realizarlo desde el centro del para conocer ms sobre simulaciones tri-
objeto? Es posible modificar este punto dimensionales con Silverlight 2 mediante
de rotacin? el uso de transformaciones y animaciones.

6 Cundo debemos usar la animacin lla- 5 Ingrese en http://silverlight.net/learn/ y


mada ColorAnimation? all busque 78708 para ver un video sobre
animaciones con Silverlight 2.
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?

186
06_Silverlight.qxp 9/30/09 1:33 PM Page 187

Silverlight Captulo 6
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 188


Ejecutar sonidos 188
Video 194
Elementos con video embebido 195
Marcadores de video 196
Deep Zoom 199
Crear el primer Deep Zoom 200
Incluir Deep Zoom
en Silverlight 203
Dibujar con InkPresenter 208
Dibujar en forma manual 212
Dibujar sobre otros elementos 215
InkPresenter y reas
de dibujo 217
Resumen 219
SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com Actividades 220
06_Silverlight.qxp 9/30/09 1:33 PM Page 188

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 Sil-
verlight. 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 (re-
produccin de videos bajo demanda). Veamos, entonces, cmo extender las capaci-
dades de este control maximizando las potencialidades que presenta.

Ejecutar sonidos
Antes de utilizar el control MediaElement para ejecutar sonidos, debemos cono-
cer los formatos soportados. Si bien el control tiene pleno soporte para los for-
matos creados por Microsoft, como el WMA (Windows Media Audio), tambin
es posible consumir un formato ms comn como el MP3. A continuacin, po-
demos 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 de-


clarar 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
06_Silverlight.qxp 9/30/09 1:33 PM Page 189

MediaElement

Debemos tener sumo cuidado al momento de colocar la ruta del recurso de soni-
do 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 re-
producir. 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 par-
tir 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 reprodu-


ciendo, as como lo que est cargando desde alguna direccin. Tengamos en cuen-
ta 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 fi-
nalizacin 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
06_Silverlight.qxp 9/30/09 1:33 PM Page 190

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 re-
produccin 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 exce-
lentes ganancias. Este lbum puede ser descargado desde la pgina http://ghosts.nin.com.

190
06_Silverlight.qxp 9/30/09 1:33 PM Page 191

MediaElement

El resultado del cdigo anterior podemos observarlo en la Figura 2, donde el conta-


dor se actualiza constantemente basado en el progreso de reproduccin del archivo
MP3. Como vemos, el control MediaElement posee todas las caractersticas necesa-
rias 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
06_Silverlight.qxp 9/30/09 1:33 PM Page 192

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#. Tam-
bin 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
06_Silverlight.qxp 9/30/09 1:33 PM Page 193

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 optimi-
zar el uso de videos, la aplicacin de efectos y movimiento sobre los objetos XAML y hasta la in-
terfaz de esta aplicacin. En http://expression.microsoft.com buscamos Learn Expression Blend.

193
06_Silverlight.qxp 9/30/09 1:33 PM Page 194

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 des-
de 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 con-
tar con algn convertidor de video a la hora de querer reproducir video con Sil-
verlight. 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
06_Silverlight.qxp 9/30/09 1:33 PM Page 195

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 vi-
sualizacin mucho ms all de la simple representacin de una pelcula en un rectn-
gulo: 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 elemen-
to 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 po-
sible 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
06_Silverlight.qxp 9/30/09 1:33 PM Page 196

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 cdi-
go, 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 de-
cir 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 ele-
gir el punto para comenzar a visualizar el video.
El control MediaElement puede leer las marcas en los videos para otorgar la mis-
ma 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
06_Silverlight.qxp 9/30/09 1:33 PM Page 197

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, escri-
biendo 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 mar-


ca del video en el momento de alcanzarla.

Figura 5. Marca alcanzada mientras se reproduce el video.

197
06_Silverlight.qxp 9/30/09 1:33 PM Page 198

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 momen-


to 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 ob-
jeto 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. Co-
mo 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
06_Silverlight.qxp 9/30/09 1:33 PM Page 199

Deep Zoom

MediaElement 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 mu-
chas ventajas en el desarrollo de aplicaciones.

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 fun-
cionalidades de acercamiento gradual o zoom. Pensemos en Deep Zoom como
en una tcnica que despliega imgenes para el cliente, quien puede acercarse y ob-
servar los detalles de estas imgenes sobre la base de su resolucin. As, si conta-
mos 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 aplica-
cin 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 ba-
lance 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 ob-
tendremos 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, ins-
trumentos 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
06_Silverlight.qxp 9/30/09 1:33 PM Page 200

6. CERRAR EL CRCULO

Crear el primer Deep Zoom


Para crear un componente Deep Zoom, necesitamos una o varias imgenes, preferen-
temente 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 nue-
vo 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 pa-
sos es acomodar estas imgenes segn cmo queramos que se visualicen, es recomen-
dable, 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 Mi-


crosoft (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
06_Silverlight.qxp 9/30/09 1:34 PM Page 201

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 bo-
tn Compose, ubicado en la parte superior de Deep Zoom Composer, accedere-
mos 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
06_Silverlight.qxp 9/30/09 1:34 PM Page 202

6. CERRAR EL CRCULO

El ltimo paso consiste en generar el proyecto exportndolo al formato que pueda en-
tender Silverlight. Para esto, presionamos sobre la ltima opcin de las tres superio-
res, 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 nues-
tra 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 al-
to 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 hubira-
mos elegido para generarlo, se nos presentar la opcin de acceder al resultado. Es-
ta 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 dife-
rentes muestreos de imgenes relacionados con las imgenes utilizadas para crear el
proyecto Deep Zoom, adems de archivos XML con meta datos.

202
06_Silverlight.qxp 9/30/09 1:34 PM Page 203

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 car-
peta es la contenedora de los resultados que obtenemos luego de la compilacin

203
06_Silverlight.qxp 9/30/09 1:34 PM Page 204

6. CERRAR EL CRCULO

de la aplicacin Silverlight y es el lugar donde se ubicar fsicamente nuestra apli-


cacin. Por eso, para tener acceso al contenido del proyecto Deep Zoom, all ten-
dremos 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
06_Silverlight.qxp 9/30/09 1:34 PM Page 205

Deep Zoom

El paso que hicimos slo mostrar el proyecto si desplegamos el estado inicial que hu-
biramos 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 co-
mo podemos ver a continuacin:

private bool RatonPresionado;


private bool RatonArrastrando;
private Point UltimaPosicionRaton;
private Point DesfaseArrastre;
private Point PosicionActual;
private 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
06_Silverlight.qxp 9/30/09 1:34 PM Page 206

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 otor-
gar excelente cdigo de ejemplo para nuestras implementaciones.

206
06_Silverlight.qxp 9/30/09 1:34 PM Page 207

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 m-
todo 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 m-
todo 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 algu-
na 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 te-
cla 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
06_Silverlight.qxp 9/30/09 1:34 PM Page 208

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 fun-
cionalidades ofrecidas hasta el momento. Existen casos dentro del desarrollo de apli-
caciones empresariales donde puede ser necesario el reconocimiento de firmas
electrnicas, que son almacenadas en bases de datos y comparadas luego para su va-
lidacin. Tambin podra ser interesante brindarle al usuario la posibilidad de
enviar tarjetas electrnicas escritas por l, dejando de lado el texto plano automati-
zado que, por lo comn, suele emplearse para este tipo de aplicaciones.
Entonces, InkPresenter es un control en Silverlight que nos otorgar una superfi-
cie de dibujado a mano haciendo uso del mouse, donde podremos capturar lo es-
crito, almacenarlo y procesarlo para su posterior uso. Adems, InkPresenter viene
acompaado de un conjunto de APIs (Application Programming Interfaces o en cas-
tellano, 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 apli-
cacin, y slo podremos dibujar sobre l. Por este motivo, el control InkPresenter
deber estar declarado por encima de cualquier otro elemento. Si algn otro com-
ponente se dibujara sobre el control InkPresenter, no podramos visualizarlo y tam-
poco 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 ma-
nera 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
06_Silverlight.qxp 9/30/09 1:34 PM Page 209

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 pre-


siona 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 pa-
ra que sea mostrada en el lienzo.
LostMouseCapture: en el momento en que el botn del mouse sea liberado o el con-
trol deje de percibir informacin desde el usuario, este evento ser disparado.

209
06_Silverlight.qxp 9/30/09 1:34 PM Page 210

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 ne-
cesario 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 caracters-
ticas 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 mis-
mo 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
06_Silverlight.qxp 9/30/09 1:34 PM Page 211

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 cap-


tura 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 crea-
do 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
06_Silverlight.qxp 9/30/09 1:34 PM Page 212

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 ba-
sados 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
06_Silverlight.qxp 9/30/09 1:34 PM Page 213

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 cre-
ada 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
06_Silverlight.qxp 9/30/09 1:34 PM Page 214

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 adiciona-


mos cada uno de los puntos, como vemos en el siguiente cdigo:

214
06_Silverlight.qxp 9/30/09 1:34 PM Page 215

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 con-
tenido del control InkPresenter. Veamos cmo hacerlo:

<InkPresenter x:Name=inkPresenter Background=#FFCBD8E4


Margin=8,8,8,8 Opacity=1
Width=384 Height=284

215
06_Silverlight.qxp 9/30/09 1:34 PM Page 216

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 des-
plegar el video y escribir sobre l. En la Figura 20 que encontramos debajo pode-
mos 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
06_Silverlight.qxp 9/30/09 1:34 PM Page 217

Dibujar con InkPresenter

InkPresenter y reas de dibujo


Si bien el control InkPresenter se muestra, por lo general, como un rectngulo, re-
sulta lo bastante verstil como para poder definir reas permitidas para dibujar so-
bre 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, es-
pecificaremos 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 en-
tender 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 debere-
mos agregar un elemento de dibujo al lienzo. Podremos usar elipses o rectngulos. Una

217
06_Silverlight.qxp 9/30/09 1:34 PM Page 218

6. CERRAR EL CRCULO

vez agregado el elemento, deberemos transformarlo a un tipo de elemento de traza-


do. 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
06_Silverlight.qxp 9/30/09 1:34 PM Page 219

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 imagi-
nacin, 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 pre-
senten el contenido de formas antes impensadas.

219
06_Silverlight.qxp 9/30/09 1:34 PM Page 220

 ACTIVIDADES

PREGUNTAS TERICAS EJERCICIOS PRCTICOS

1 Qu formatos de audio soporta Silverlight 2? 1 Intente reproducir sonidos desde una di-
reccin web remota, haciendo uso del con-
2 Mediante qu mtodos podemos saber la trol MediaElement.
posicin actual de reproduccin de un soni-
do o msica? 2 InkPresenter para Windows Presentation
Foundation posee la capacidad de recono-
3 Qu mtodo es necesario ejecutar para cer la escritura y transformarla a letras.
quitar el sonido por completo de una re- Intente implementar esta caracterstica.
produccin en curso?
3 Recolecte la informacin creada con Ink-
4 Qu control necesitamos para reproducir Presenter y almacnela en formato XML.
video en las aplicaciones Silverlight 2?
4 Con la informacin recolectada en el ejer-
5 Cules son los formatos de video que pue- cicio anterior, trate de volver a mostrarla
den ser manejados por Silverlight 2? en la aplicacin Silverlight 2.

6 A qu hace referencia la tecnologa Deep 5 Teniendo diferentes imgenes, intente


Zoom? crear una presentacin Deep Zoom. Con la
informacin que este componente retorna,
7 Qu control XAML necesitamos utilizar pa- muestre informacin en una aplicacin Sil-
ra incluir un elemento Deep Zoom dentro verlight 2 basada en la imagen que el usua-
de nuestra aplicacin Silverlight 2? rio est visualizando.

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?

220
07_Silverlight.qxp 9/30/09 1:35 PM Page 221

Silverlight Captulo 7
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 Ampliar las funcionalidades 222


Silverlight desde C# 222
WebClient 230
o el clima son slo una parte del todo
Enviar informacin 233
Almacenamiento aislado 239
que puede ser construido, y Silverlight Implementar
el almacenamiento aislado 240
no queda exento. Veamos el porqu. Capacidad de almacenamiento 245
Almacenar configuraciones 247
OpenFileDialog 251
Manejo de hilos 255
El concepto de hilos 256
Temporizador 257
Personalizar los hilos 259
Hilos y eventos 261
Consumir servicios desde
Silverlight 263
Crear un servicio WCF 270
Manipular datos 275
Enlazado de datos 276
LinQ 283
Resumen 287
SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com Actividades 288
07_Silverlight.qxp 9/30/09 1:35 PM Page 222

7. INTERCONEXIN

AMPLIAR LAS FUNCIONALIDADES


Si bien en los captulos vistos hasta ahora hemos hecho uso de C# para potenciar al-
gunas de las funcionalidades de Silverlight, debemos reconocer que la mayora del tra-
bajo 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 as-
pectos 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 pos-
terioridad. En este captulo hablaremos de estas cualidades por medio de ejemplos va-
riados, 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 en-
contrar la mejor forma posible de mover elementos por la pantalla y simular anima-
ciones 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 con-
trol 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 223

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 ima-
gen 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 224

7. INTERCONEXIN

public Page()
{
InitializeComponent();
CrearTablero();
}

Canvas[] vectorCanvas = new Canvas[16];


Image[] imagenes = new Image[16];
int[] tablero = new int[16];

private void CrearTablero()


{
Uri uri = new Uri(Froblins4.png, UriKind.Relative);
int n = 0;
for (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
07_Silverlight.qxp 9/30/09 1:35 PM Page 225

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 po-
demos 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 sec-
cin 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 li-
mitar 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 mez-
clar 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 226

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 void dibujarTablero()


{
int x = 0;
int y = 0;
for (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 nue-


vo 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 ver-
lo en la Figura 2, que aparece en la prxima pgina.

226
07_Silverlight.qxp 9/30/09 1:35 PM Page 227

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 conti-
guo, 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 228

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 - 1) ||
(espacioTablero == espacioVacio + 4) ||
(espacioTablero == espacioVacio - 4))
{
int x = espacioVacio / 4;
int y = espacioVacio % 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. Es-
tos eventos pueden ser vistos en la siguiente direccin: www.youtube.com/marchmadness.

228
07_Silverlight.qxp 9/30/09 1:35 PM Page 229

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 en-
lazado 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 se-
leccionar, modificar la dificultad agregando ms divisiones a la imagen, etctera. Nuestro nico
lmite es la imaginacin.

229
07_Silverlight.qxp 9/30/09 1:35 PM Page 230

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 for-
ma 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 algu-
na 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 ma-
nipular las consultas sobre el contenido. Como primera instancia, crearemos los
controles XAML donde se mostrarn los resultados de la consulta.

<UserControl xmlns:data=clr-
namespace: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
07_Silverlight.qxp 9/30/09 1:35 PM Page 231

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 fuen-


te 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 even-
tos que se dispararn sobre la base de las acciones que realicemos.

DownloadProgressChanged: se disparar en el momento en el que una llamada asn-


crona de descarga de contenidos pueda transferir toda o parte de la informacin.
DownloadStringCompleted: se ejecuta siempre que un elemento descargado de ma-
nera asncrona se ha descargado por completo.
OpenReadCompleted: ocurre cuando una accin de lectura de un recurso de ma-
nera 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 en-
vo de informacin ha transferido todo o una porcin de los datos.

231
07_Silverlight.qxp 9/30/09 1:35 PM Page 232

7. INTERCONEXIN

UploadStringCompleted: ocurre cuando finaliza una accin de envo de informacin.


WriteStreamClosed: en el momento en que una operacin de escritura se ha com-
pletado, 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 233

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 (resulta-
dos), 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 im-
portantes 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. Po-
demos hacer uso del mismo modelo antes planteado, pero adicionndole parmetros

233
07_Silverlight.qxp 9/30/09 1:35 PM Page 234

7. INTERCONEXIN

que se incluirn en el envo de la informacin. Esta informacin podr ser maneja-


da 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 res-
puesta 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 cues-
tin. 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 235

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 peticio-
nes 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 236

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 refe-
rente 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 enviar-
lo 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 237

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 pre-
sencia 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 238

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 usua-
rio 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, adi-
cionamos 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, debere-
mos 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 dese-
ados. Cross Site Scripting o SQL Injection son dos de las vulnerabilidades ms comunes.

238
07_Silverlight.qxp 9/30/09 1:35 PM Page 239

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 consumi-
do 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 alma-
cenamiento aislado en Silverlight presenta otras caractersticas. Pensemos en esta
funcionalidad como en la posibilidad de tener una parte del disco duro de la m-
quina 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 aho-
rramos 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 240

7. INTERCONEXIN

acceso a archivos en el equipo del usuario. De esta forma, se aseguran de que dife-
rentes 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, po-
dremos 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 pa-
ra 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 apli-
cacin. Una vez que tenemos esta referencia, todo lo que leamos o escribamos pasa-
r 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 cre-
ar, 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 espe-


cificar un nombre para el directorio.
DeleteDirectory: borra un directorio del almacn.
CreateFile: crea un nuevo archivo, retornando un objeto IsolatedStorageFileStream.

240
07_Silverlight.qxp 9/30/09 1:35 PM Page 241

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 ob-
jeto 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 bo-
tn. 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 ob-
servar el resultado obtenido con lo que hemos realizado.

241
07_Silverlight.qxp 9/30/09 1:35 PM Page 242

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. Po-
dremos 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 243

Almacenamiento aislado

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

En este caso, el contenido del archivo es recuperado y almacenado en una variable tem-
poral 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 po-
see 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 exis-
te, 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 adicio-
nar 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 244

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 ope-
rativo. En este caso, se ubican en las carpetas que contienen informacin del usuario.

Figura 12. Ubicacin del archivo creado en el almacn.

244
07_Silverlight.qxp 9/30/09 1:35 PM Page 245

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 es-
pacio. 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 po-
der pasar por alto este tipo de validaciones, estaramos en condiciones de vulne-
rar 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 tan-
to 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 cuo-
ta 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 246

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 dispo-
nible, 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 ac-


ceder a esta informacin presionando el botn derecho del mouse y seleccionando
la opcin Silverlight en el men desplegable. Al hacerlo, veremos todas las propie-
dades de la aplicacin en ejecucin. En la ltima pestaa, aparecern las propieda-
des 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 247

Almacenamiento aislado

Almacenar configuraciones
Es posible que necesitemos almacenar valores como textos u objetos complejos, pe-
ro 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 almacena-
miento 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 obje-
to. 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 ma-


neja 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 inicial-
mente este espacio de almacenamiento.

247
07_Silverlight.qxp 9/30/09 1:35 PM Page 248

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 rempla-
zado 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();
}

ApplicationSettings retornar un tipo de datos Object, por lo que es necesario trans-


formarlo 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 almace-
nados desde un navegador son visibles en el otro.

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 es-
tas variables de configuracin. De cualquier manera, es necesario que tengamos en
cuenta que slo podrn ser almacenados aquellos elementos que contengan la cua-
lidad de ser serializados. Esto quiere decir que podremos almacenar elementos,

248
07_Silverlight.qxp 9/30/09 1:35 PM Page 249

Almacenamiento aislado

cuyos tipos de datos puedan ser transformados a XML. Para ilustrar esta posibili-
dad, crearemos una coleccin de entidades, alojndolas primero en una variable de
configuracin que luego recuperaremos para llenar un control DataGrid.

<UserControl xmlns:data=clr-
namespace: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 alma-
cenar 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 250

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 modi-
ficacin. 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 se-
gundo 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 en-
tidad. 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 251

Almacenamiento aislado

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

OpenFileDialog
OpenFileDialog es un control homnimo del usado en aplicaciones de escritorio. Per-
mite 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 alojar-
las en un servidor. El cdigo para crear un objeto del tipo OpenFileDialog es:

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
07_Silverlight.qxp 9/30/09 1:35 PM Page 252

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
07_Silverlight.qxp 9/30/09 1:35 PM Page 253

Almacenamiento aislado

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

Podremos agregar tantos filtros como creamos necesarios. Para lograr esto, modifi-
caremos 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 254

7. INTERCONEXIN

Es posible combinar el uso del objeto OpenFileDialog con la funcionalidad de alma-


cenamiento 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 255

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 bina-
ria. 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 escrito-
rio, donde es posible ejecutar ms de un proceso, funcin o pieza de cdigo de ma-
nera 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 pro-
cesos 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 aplica-
cin, podra resultar poco prctico. De esta forma, estos procesos de alta com-
plejidad 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 fir-
ma 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, de-
bemos 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 256

7. INTERCONEXIN

El concepto de hilos
En los diferentes captulos ya hemos tenido algunos contactos con el manejo de hi-
los. 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 eje-
cucin distinto del primario definido por la aplicacin, disparando eventos basados
en ciertos estmulos ya configurados. Esto es posible debido a que el sistema opera-
tivo 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 desarrolla-
mos 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 frac-
cin de tiempo a cada una de estas aplicaciones para que puedan realizar sus traba-
jos. 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. Debi-
do a esto, tener una tarea que capte todo el tiempo disponible otorgado por el sis-
tema 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 apli-
cacin, lo que hace que no podamos interactuar con ella hasta que el bucle finalice

256
07_Silverlight.qxp 9/30/09 1:35 PM Page 257

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 tempori-
zador es llamado DispatcherTimer y cumple la funcin de disparar un evento basa-
do 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, de-
bemos 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 258

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 apli-
car 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 ac-


tualizado dentro del rango de tiempo fijado por el control DispatcherTimer.

258
07_Silverlight.qxp 9/30/09 1:35 PM Page 259

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 reali-
zar 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 po-
sible 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 260

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, es-
cribimos 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 per-
siste ya que seguiremos bloqueando el hilo principal de ejecucin, a menos que eje-
cutemos 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 asn-
crona. 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 previamen-
te. 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 vi-
sual 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 al-
terarse 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 261

Manejo de hilos

Hilos y eventos
Podemos llegar an ms lejos con Silverlight y el uso de hilos de ejecucin si im-
plementamos eventos. Si bien ya estamos familiarizados con los eventos debido
a que hemos hecho uso de ellos con la implementacin de botones, listas des-
plegables 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 es-
pecialmente 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 su-
ceder diferentes hitos, nos avise de estos hechos para que el cdigo que hubiera
iniciado el nuevo proceso sepa cmo reaccionar basado en estos cambios. Pode-
mos 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 noti-
ficacin por parte del evento. En este caso, la funcin que implemente este even-
to 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 progre-
so 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 ma-


nera 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 fun-
cin apuntada desde otros mtodos y procesos.

261
07_Silverlight.qxp 9/30/09 1:35 PM Page 262

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, ob-
tendremos un error de referencia no inicializada. Para solucionar este problema, es re-
comendable 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 263

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 infor-
macin 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, simu-
lando 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 consu-
mir informacin de servicios creados por nosotros y que trabajen en nuestro si-
tios 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 264

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, notare-
mos que no existe diferencia alguna con un mtodo o funcin tradicional del lengua-
je 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 265

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 apar-
tado http://localhost que hace referencia a nuestro equipo. El siguiente paso es el
de adicionar esta referencia al servicio dentro de nuestra aplicacin Silverlight. Pa-
ra 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 en-
tre 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 pro-
tocolo, s es necesario mencionar que, en el caso de Silverlight, usaremos SOAP pa-
ra 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 266

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 n-
meros 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 mun-
do 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 267

Consumir servicios desde Silverlight

El siguiente paso consiste en tomar los valores introducidos por el usuario, conec-
tarse 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 l-
timo, 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 su-
ma, 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 268

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 aplica-
cin Silverlight desde el servicio web. Para esto, tendremos que agregar un nuevo
mtodo web que retorne dicha entidad, como vemos a continuacin:

268
07_Silverlight.qxp 9/30/09 1:35 PM Page 269

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 re-
tornado 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 270

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 mencio-
nar 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 hos-
pedar 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. Lue-
go, 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 usa-
do, posee dos atributos nuevos para identificar el servicio y los mtodos expuestos:

ServiceContract: este contrato de servicio, distingue la clase que ser expuesta co-
mo un servicio. Esta clase puede contener diferentes mtodos expuestos.
OperationContract: los contratos de operacin representan cada uno de los mto-
dos o funciones expuestos por el servicio y con los cuales se podr interactuar.

[ServiceContract(Namespace = )]
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]

270
07_Silverlight.qxp 9/30/09 1:35 PM Page 271

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, re-
presentado 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 apli-
caciones y el detalle de las excepciones que ste arroja. Con el servicio configurado,
slo nos resta crear la implementacin del contrato.

271
07_Silverlight.qxp 9/30/09 1:35 PM Page 272

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 po-
demos 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 273

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 tan-
to 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) especfi-
ca. 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 274

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 escri-
tos en la consola de depuracin, como vemos en la siguiente imagen.

274
07_Silverlight.qxp 9/30/09 1:35 PM Page 275

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 inter-
conectarlo 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 re-
lacionados en forma directa con productos Microsoft, como Windows.

MANIPULAR DATOS
En el desarrollo de aplicaciones empresariales, uno de los puntos fuertes es la ma-
nipulacin 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 desarrolla-
dores se enfrentan a cada momento. Por esto, es necesario tambin poder contar
con formas fciles y rpidas de realizar estas tareas. Silverlight implementa varas tc-
nicas 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, po-
damos 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 276

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 da-
tos, pero desde el punto de vista de la programacin orientada a objetos. Esto quie-
re 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, hacien-
do 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 auto-
mtica. 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 volme-
nes de informacin pueden requerir mucho esfuerzo para su construccin. Adems,
pueden incurrir en costos de mantenimiento. Si agregramos o modificramos algu-
na de las propiedades del objeto contenedor de datos, tendramos que cambiar tam-
bin 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 solu-
cionar 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 toma-
r este valor y lo aplicar en tiempo de ejecucin. As, si necesitramos modifi-
car 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 277

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
07_Silverlight.qxp 9/30/09 1:35 PM Page 278

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 con-
tenedor 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 contro-
les 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 desplega-
dos 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 279

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 in-
formacin, 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 280

7. INTERCONEXIN

Esto se debe a que es posible especificar la forma en la que los controles con datos en-
lazados 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 cuan-
do el control sufra un cambio. De esta forma, si el usuario modificara el texto des-
plegado 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 valo-


res 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 281

Manipular datos

En el ejemplo anterior hemos usado, como tipo de dato base para todos los valo-
res, 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 va-
lor no soportado por ese tipo de datos, por ejemplo, un campo numrico para alo-
jar 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 inter-
faz 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 solucio-
narlo. 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 s-
lo 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 en-
lazado de datos previamente usada, ahora hemos agregado dos nuevos atributos:

281
07_Silverlight.qxp 9/30/09 1:35 PM Page 282

7. INTERCONEXIN

ValidatesOnExceptions, 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 dispara-
r 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 decla-
rar y capturar el evento disparado por el validador desde este punto.

<Grid x:Name=LayoutRoot Background=White


BindingValidationError=LayoutRoot_BindingValidationError>
<Grid.RowDefinitions>
...

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 usua-
rio 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 283

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 orien-
tado a objetos. Es destacable la presencia de LinQ en Silverlight ya que, por el peque-
o 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 aditamen-
tos. 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 ele-
mentos 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 284

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. Co-
mo 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 orde-
nar 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 285

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 modi-
ficarlo 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 286

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 consul-


ta 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. Se-
lecciona 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 ba-
sados en una llave comn.
Concat: operador de concatenacin.
OrderBy/ThenBy/OrderByDescending/ThenByDescending: operadores de ordena-
miento, tanto ascendentes como descendentes.
Reverse: operador de ordenamiento que se encarga de revertir el orden de la se-
cuencia 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
07_Silverlight.qxp 9/30/09 1:35 PM Page 287

Manipular datos

Estos operadores pueden ser aplicados a cualquier lista de objetos o a cualquier ele-
mento 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 necesite-
mos 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 de-
ms elementos de la entidad. LinQ tiene mucho potencial, por lo que no debere-
mos 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 recono-
ceremos 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 c-
digo 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 tecno-
logas 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 de-
sarrollo de aplicaciones web de alto nivel.

287
07_Silverlight.qxp 9/30/09 1:35 PM Page 288

 ACTIVIDADES

PREGUNTAS TERICAS EJERCICIOS PRCTICOS

1 En qu casos deberemos usar el objeto 1 Intente ampliar el ejemplo de utilizacin de


WebClient? LinQ, incorporando controles XAML con la
lista de filtros y permitirle al usuario inte-
2 Qu evento del objeto WebClient debere- ractuar con los datos y las bsquedas.
mos usar si queremos saber el progreso de
la descarga del elemento por consumir 2 Para saber ms sobre Windows Communi-
desde nuestra aplicacin Silverlight 2? cation Foundation, ingrese en http://msdn.
microsoft.com y busque informacin.
3 Qu versin del lenguaje C# y de Microsoft
.Net Framework podemos utilizar en las 3 Cree un modelo de objetos propio para
aplicaciones Silverlight 2? almacenar informacin. Recolecte esa
informacin ingresada por el usuario y
4 Qu es un HTTPHandler? envela a un servicio web para que ste se
encargue de almacenarla en una base de
5 Cul es el concepto detrs del almacena- datos distante.
miento aislado?
4 Haciendo uso de eventos e hilos de ejecu-
6 Cmo podemos adquirir mayor capacidad cin, cree un temporizador personalizado.
de almacenamiento dentro del rea designa-
da para cada usuario en el almacn aislado? 5 Para saber ms sobre el manejo de hilos de
ejecucin, ingrese en el sitio web oficial de
7 En el almacenamiento aislado, slo se MSDN: http://msdn.microsoft.com/es-es.
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 comple-


jos retornados por servicios web desde
Silverlight 2?

10 Es posible en Silverlight 2 enlazar datos


desde fuentes de datos de forma dinmica?

288
08_Silverlight.qxp 9/30/09 1:36 PM Page 289

Silverlight Captulo 8
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


Conectar tecnologas 290
Silverlight 2 y el HTML 290
con estas tecnologas comunes. HtmlDocument y HtmlElement 292
HtmlPage 300
HtmlWindow 305
Cookies 314
Modificar CSS 317
Silverlight 2 y JavaScript 320
Llamar funciones 323
Objetos Silverlight
para JavaScript 324
Resumen 327
SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com Actividades 328
08_Silverlight.qxp 9/30/09 1:36 PM Page 290

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 faci-
lita desde la generacin de contenido dinmico hasta validaciones de las entradas del
usuario. Junto con JavaScript, podemos encontrar el lenguaje de etiquetas que da vi-
da 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 tecno-
logas 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 compor-
tamiento 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 nues-
tras pginas web, desde dentro de la aplicacin Silverlight, y al mismo tiempo, su in-
trprete, instalado en el navegador cliente y que hace uso del lenguaje JavaScript, per-
mite 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 in-
teractuar 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 cuen-
ta 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 to-
do 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/x-
silverlight-2 width=100% height=100%>
<param name=source value=ClientBin/Capitulo8HTML.xap/>
<param name=onerror value=onSilverlightError />
<param name=background value=white />

290
08_Silverlight.qxp 9/30/09 1:36 PM Page 291

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 eje-
cutar la aplicacin Silverlight, sta debe ser declarada en el lenguaje que el navega-
dor 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 ob-
jetos 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 cap-
turar informacin del navegador en el que est corriendo la aplicacin, abrir venta-
nas 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 con-
tenidos 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 na-
vegar a otras pginas o saltar entre diferentes marcadores dentro de la misma pgina.
HttpUtility: nos otorga un conjunto de herramientas de cdigo para realizar tare-
as sobre el HTML. Codificar y decodificar los parmetros enviados desde la p-
gina original hacia una pgina destino.
ScriptableTypeAttribute/ScriptableMemberAttribute: atributos que pueden ser aplica-
dos 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 292

8. EL NAVEGADOR Y SU DOMINIO

HtmlDocument y HtmlElement
Con HtmlDocument es posible modificar e interactuar con la estructura HTML pre-
sente 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 aplica-


cin web es mostrada en un TextBox.

Figura 1. Direccin URL donde se hospeda la aplicacin Silverlight.

HtmlDocument 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:

<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
08_Silverlight.qxp 9/30/09 1:36 PM Page 293

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 apli-
cacin 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 294

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 va-
lor incluido en el atributo ID del componente. Luego, usando GetAttribute, refe-
renciamos 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 re-
sida 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 295

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 con-
troles HTML de la pgina web. El comportamiento, por el contrario, es ms cer-
cano 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 particula-
ridad de servir de contenedor de otras etiquetas HTML y, como tal, tambin es po-
sible modificar su estructura HTML desde cdigo JavaScript mediante el uso de la
propiedad innerHTML. Entonces, podramos hacer uso de innerHTML desde la apli-
cacin Silverlight para crear cdigo HTML dentro de esta etiqueta.

private void Button_Click_2(object sender, RoutedEventArgs e)

295
08_Silverlight.qxp 9/30/09 1:36 PM Page 296

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 ca-
dena 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 con-
forman 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 usua-
rio hubiera completado el campo de texto.
En caso de que tengamos que realizar una aplicacin que no slo trabaje con navega-
dores 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, ob-
jeto que permite la manipulacin de elementos individuales dentro de la pgina HTML.

private void Button_Click_3(object sender, RoutedEventArgs e)


{

296
08_Silverlight.qxp 9/30/09 1:36 PM Page 297

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 con-
trol 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 pa-
trn de creacin de elementos HTML:

private void Button_Click_4(object sender, RoutedEventArgs e)


{

297
08_Silverlight.qxp 9/30/09 1:36 PM Page 298

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 servi-


dor 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 in-
troducida 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 299

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 hubie-
se interactuado con cajas de texto, listas desplegables y otros controles podra no-
tificar 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 ve-


mos 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 300

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 ingre-
sar 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 301

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, obten-
dremos 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 302

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 tam-
bin deberemos definir una direccin URL, el nombre de la nueva instancia y una
serie de opciones para configurar la ventana emergente. Las opciones de configu-
racin de la ventana emergente pueden ser importantes a la hora de obtener un
comportamiento visual especfico. Podemos ver la lista de opciones dentro del ob-
jeto 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 bor-
de izquierdo de la pantalla.
Directories: esta opcin muestra u oculta los marcadores o vnculos del nave-
gador 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 tama-
o la ventana emergente una vez creada.
Scrollbars: esta opcin muestra u oculta las barras de desplazamiento, tanto ho-
rizontales 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 303

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 acep-
tadas por todos los usuarios, los navegadores actuales cuentan con mecanismos para
bloquear estas ventanas, haciendo que no puedan abrirse a menos que el usuario espe-
cifique lo contrario. Debido a esto, si ejecutamos el cdigo en forma directa y el nave-
gador 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 pa-
ra 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 304

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 ejem-
plo 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 abier-
ta 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 pre-
siona sobre el segundo botn de la aplicacin Silverlight, redirigiremos el conte-
nido de la ventana a otro sitio web.

HtmlWindow window;

private void Button_Click(object sender, RoutedEventArgs e)


{
if (HtmlPage.IsPopupWindowAllowed)
{

304
08_Silverlight.qxp 9/30/09 1:36 PM Page 305

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 re-
presenta 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 306

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 aplica-
cin y no evada ciertas reglas necesarias en nuestro cdigo. El siguiente cdigo otor-
ga 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 pre-
sionar 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 307

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
08_Silverlight.qxp 9/30/09 1:36 PM Page 308

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
08_Silverlight.qxp 9/30/09 1:36 PM Page 309

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 pre-


sione 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 re-


side la aplicacin Silverlight, podramos abrir una nueva pgina, similar a la ge-
nerada 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 pue-
de, en ningn caso, modificar por cdigo estos valores.

309
08_Silverlight.qxp 9/30/09 1:36 PM Page 310

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 identifi-
que 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, po-
dremos 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 311

Silverlight 2 y el HTML

Notemos la concordancia entre el nombre del marcador HTML y el nombre utiliza-


do 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 marcado-
res, 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 mostran-
do 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 par-
te es la que quiere ver el usuario. Pero, aplicando marcadores a la aplicacin, es po-
sible 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 Sil-
verlight (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
08_Silverlight.qxp 9/30/09 1:36 PM Page 312

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
08_Silverlight.qxp 9/30/09 1:36 PM Page 313

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
08_Silverlight.qxp 9/30/09 1:36 PM Page 314

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 gene-
rar, 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 siem-
pre, 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 aque-
llos 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 computado-
ra, que leern posteriormente para as recuperar eso que haban almacenado.
Desde una aplicacin Silverlight es posible, tambin, leer cookies que hayan sido cre-
adas 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 315

Silverlight 2 y el HTML

es limitada, estos elementos se guardan en el equipo del cliente y pueden ser compar-
tidos con otros ambientes de desarrollo. Estas cookies podran ser manipuladas desde
una aplicacin ASP.net, como por JavaScript. Por este motivo, las cookies pueden con-
vertirse en un buen canal de comunicacin entre las distintas plataformas.
En el siguiente ejemplo, crearemos una cookie desde ASP.net, que leeremos y mo-
dificaremos 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: Font-
Names=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 l-
neas 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 316

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 me-
diante el identificador de ; (punto y coma). Adems, las cookies sern almacena-
das con la estructura [Nombre]=[Valor], por lo que, delante del signo igual en-
contraremos 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 317

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 des-
de 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 318

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 cuan-
do necesitemos informar al usuario de algn acontecimiento modificando la ti-
pografa 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 tama-
o 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 vi-
suales a textos, imgenes, colores de fondo, posicin de distintos elementos y otros aspector pa-
s 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 319

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 identifica-


dor del elemento, estaremos en posicin de modificar el estilo por otro de la lista de es-
tilos 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 320

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 Silver-
light, tambin es posible hacerlo con el cdigo JavaScript que se ejecuta en el navega-
dor. 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 implemen-

320
08_Silverlight.qxp 9/30/09 1:36 PM Page 321

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, pue-
de potenciar mucho ms las posibilidades de desarrollo de aplicaciones web. Como
primera instancia, asociaremos un evento JavaScript a un elemento HTML que, cuan-
do 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 tra-
bajando 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 lgi-

321
08_Silverlight.qxp 9/30/09 1:36 PM Page 322

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 pro-
ducidos 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 dar-
nos 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 modifica-
cin. 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 ca-
sos, 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. Jun-
to 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 elemen-
to, 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 even-
to 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 lista-


dos. Debemos tener en cuenta que algunos eventos slo son soportados por ciertos
navegadores, por lo que deberamos utilizarlos con cuidado.

322
08_Silverlight.qxp 9/30/09 1:36 PM Page 323

Silverlight 2 y JavaScript

Llamar funciones
Como dijimos, tambin es posible llamar a funciones JavaScript desde cdigo Sil-
verlight. 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 ex-
tender 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 324

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 alber-
gar 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 en-
cargaba de la ejecucin de funciones JavaScript, as como de la captura de eventos des-
de 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 implemen-
tacin por parte de JavaScript acarreara mucho ms esfuerzo. Para lograr esto, es ne-
cesario 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 325

Silverlight 2 y JavaScript

La primera lnea, ScriptableType(), marca la clase como un tipo que podr ser con-
sumido 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 m-
todos 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 pgi-


na 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 lla-
mada para este caso desde el evento onclick de un botn HTML.

<input type=button value=Mostrar mensaje onclick=Mostrar(); />

325
08_Silverlight.qxp 9/30/09 1:36 PM Page 326

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 instan-
ciada 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 ins-
tancia, 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 instan-
cia de este objeto en JavaScript, deberemos hacer lo siguiente:

326
08_Silverlight.qxp 9/30/09 1:36 PM Page 327

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 crea-
da 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 tra-
dicional 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 consu-
mirlo 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
08_Silverlight.qxp 9/30/09 1:36 PM Page 328

 ACTIVIDADES

PREGUNTAS TERICAS EJERCICIOS PRCTICOS

1 Qu objeto debemos usar desde Silverlight 2 1 Visite el sitio de CodePlex (www.codeplex.


para obtener informacin de la pgina com/IronPython), para informarse de c-
HTML contenedora de la aplicacin? mo implementar tecnologas tales como
IronPython y Silverlight 2.
2 Es posible modificar los valores de los
objetos creados en el cdigo HTML desde 2 Para conocer ms sobre el uso de reflexin
Silverlight 2? sobre Microsoft .Net, ingrese en http://
msdn.microsoft.com/es-es/.
3 Cundo se usa el mtodo GetElementById
desde Silverlight 2? 3 Modifique el ejemplo de navegacin por
marcadores para incluir un nuevo control.
4 Cmo podemos ejecutar el envo de un for-
mulario web desde Silverlight 2? 4 Con el nuevo control creado en el ejercicio
anterior, utilice cookies para dirigir al
5 Cmo podemos lanzar una nueva ventana usuario a la pgina que estaba viendo, en
del navegador desde Silverlight 2? la aplicacin Silverlight, antes de cerrar la
ventana del navegador.
6 Qu es una cookie?
5 Pruebe crear una aplicacin Silverlight que
7 Cmo leemos y escribimos cookies desde se visualice en modo de pantalla completa.
Silverlight 2?

8 Cmo podemos ejecutar cdigo JavaScript


desde Silverlight 2?

9 Qu atributo decorativo necesitamos utili-


zar para que el cdigo Silverlight pueda ser
ejecutado desde JavaScript?

10 Qu eventos JavaScript se disparan slo


por medio de la accin del usuario? Nom-
bre algunos de ellos.

328
09_Silverlight_Apendice.qxp 9/30/09 1:37 PM Page 329

Silverlight Apndice A
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.

Proyecto Moonlight 330


Sistemas operativos 330
Versiones de Moonlight 331
Herramientas de desarrollo 331
SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com Problemas conocidos 333
09_Silverlight_Apendice.qxp 9/30/09 1:37 PM Page 330

APNDICE A. SILVERLIGHT FUERA DE WINDOWS

PROYECTO MOONLIGHT
Moonlight es un proyecto creado por la comunidad de desarrolladores y patro-
cinado 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 usua-
rios, sin importar su sistema operativo e, incluso, su navegador. Teniendo en
cuenta que de manera nativa Silverlight es soportado por Opera, Internet Ex-
plorer 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 SISTEMA OPERATIVO FIREFOX 2.0 FIREFOX 3.0
x86 (32 Bits) SUSE Linux Enterprise Desktop 10 S S
openSUSE 11.0 S S
openSUSE 11.1 S S
Ubuntu 8.04 S S
Fedora Core 9 S S
x86-64 (64 bits) SUSE Linux Enterprise Desktop 10 S S
openSUSE 11.0 No S
Tabla 1. Sistemas operativos y navegadores web soportados por Moonlight.

330
09_Silverlight_Apendice.qxp 9/30/09 1:37 PM Page 331

Proyecto Moonlight

En cuanto a requerimientos, para ejecutar una aplicacin Silverlight desde Firefox, de-
beremos 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 sali-
da 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 li-
berada. 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 sali-
da de estos productos y tecnologas, analizarlos, estudiarlos, para luego poder imple-
mentarlos. 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 mis-
mo usado por Moonlight, los creadores de ste no recomiendan el uso de Visual
Studio 2008 para la creacin de aplicaciones Silverlight especficas para Linux. Es-
to 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 qui-
siramos 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 cre-


adas 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
09_Silverlight_Apendice.qxp 9/30/09 1:37 PM Page 332

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 desarro-
llo con Mono, lo que quiere decir que nos proveer herramientas no slo para el de-
sarrollo 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. s-
te es libre y de cdigo abierto. Por tal motivo, si deseamos colaborar en su mejora con-
tamos 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 alterna-
tivas gratuitas que hallaremos en Internet. Por ejemplo, TortoiseSVN, una de las re-
comendadas 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 especi-
fico, 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
09_Silverlight_Apendice.qxp 9/30/09 1:37 PM Page 333

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 ofi-
ciales de Silverlight, otros problemas relacionados con la funcionalidad misma de

333
09_Silverlight_Apendice.qxp 9/30/09 1:37 PM Page 334

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 funcionalida-
des presentes en Microsoft .Net Framework 3.0 y 3.5, puede que la mayora del c-
digo 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 desa-


rrolladora 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 com-
ponente 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 ti-
po de emprendimientos y desarrollos que nos permiten obtener mayor cantidad y
mejor calidad de productos de software.

334
10_Silverlight_Apendice-b.qxp 9/30/09 1:38 PM Page 335

Silverlight Apndice B
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.

Silverlight 3 336
Nuevos controles 336
Efectos en tres dimensiones 337
Uso de Pixel Shader 338
SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com Fuera del navegador 339
10_Silverlight_Apendice-b.qxp 9/30/09 1:38 PM Page 336

APNDICE B. SILVERLIGHT 3, LA NUEVA GENERACIN

SILVERLIGHT 3
Silverlight 3 viene con grandes mejoras para el desarrollador, algo que tambin se tra-
duce en progresos para el usuario. Mejor uso del hardware del equipo cliente, imple-
mentacin 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 en-
trega de nuevas tecnologas, incorpore mayores controles de aquellos que recono-
ce 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 ob-
tener esta informacin, este control nos mostrar los datos de cmo hacerlo.

 ACTUALIZARSE

Para mantenerse actualizado sobre las nuevas funcionalidades incluidas en Silverlight 3, po-
demos 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
10_Silverlight_Apendice-b.qxp 9/30/09 1:38 PM Page 337

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 es-
pacio tridimensional. Si bien no incluye, an, el manejo de objetos tridimensionales
de forma nativa, s es posible simular este comportamiento mediante un nuevo con-
junto de transformaciones. Estas transformaciones son llamadas proyecciones, y tra-
bajan 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 pro-
yeccin no era necesariamente correcto.

337
10_Silverlight_Apendice-b.qxp 9/30/09 1:38 PM Page 338

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 proyec-
cin 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 sali-
da 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 efec-
tos 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
10_Silverlight_Apendice-b.qxp 9/30/09 1:38 PM Page 339

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 ni-
vel 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 caracte-
rstica 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 aho-
ra puede quedarse en el escritorio y ejecutarse desde ste. Podremos configurar estas ca-
ractersticas desde las propiedades del proyecto, como vemos en la siguiente figura:

Figura 4. Configuraciones necesarias


para utilizar la aplicacin desde el escritorio.

339
10_Silverlight_Apendice-b.qxp 9/30/09 1:38 PM Page 340

APNDICE B. SILVERLIGHT 3, LA NUEVA GENERACIN

Al instalar y ejecutar la aplicacin desde el escritorio, veremos el mismo comporta-


miento 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 Sil-
verlight 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
11_Silverlight_servicios.qxp 9/30/09 1:39 PM Page 341

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.

ndice temtico 342


SERVICIO DE ATENCIN AL LECTOR: usershop@redusers.com Sitios web recomendados 345
11_Silverlight_servicios.qxp 9/30/09 1:39 PM Page 342

SERVICIOS AL LECTOR

NDICE TEMTICO
A Cookies 314
AJAX 15 CookieSilver 315
Almacenamiento aislado 239 CSS 178, 317
Animaciones 19, 45, 170, 175 Cursor 88
App.Config 271
AS 250 D
ASP.net 64, 317 Data 57, 218
Autocompletar 336 DataContext 278
AutoUpgrade 58 DataGrid 60, 68, 75, 132, 168, 231
DatePicker 60, 137, 147
B DateTime 135, 145
Background 48 Deep Zoom 199, 331
Barras de desplazamiento 98 Depuracin 62
Binding 276 Dibujar 213
BlackoutDates 142 Dibujo 46
Bool 135 DispatcherTimer 257
Border 48, 101, 168, 183 DisplayDate 143
BorderThickness 102 DisplayMode 250
Button 67, 103, 183 Distorsin 167
DLR 21
C DoubleAnimation 171
Caja de texto 128
Calendar 60, 139 E
Canvas 24, 92, 222, 229 Escalar 165
CheckBox 106, 123 Estilo 178
Clases 40 Etiquetas 22, 290
Class 318 Evento 72, 83, 261
Click 51, 71, 74, 103, 107, 198 Expression Blend 26, 30
ClientBin 203
Clip 217, 225 F
CLR 21 Flash 15
ColorAnimation 173 FontFamily 127
ComboBox 117 FontSize 127
Componentes 46, 67 FontWeight 127
Context 236
Contrasea 130 G
Controles 24 GetAttribute 294
Controles 46, 67 GetElementById 294

342
11_Silverlight_servicios.qxp 9/30/09 1:39 PM Page 343

ndice temtico

GotFocus 84 L
Grid 67, 84, 89, 279 LayoutUpdated 84
GridSplitter 89 LinQ 21, 63, 74, 283
Grilla 47 ListBox 124, 252
GroupName 110 LostFocus 84

H M
Height 39, 85, 125, 302 Marcador 196
Hilos 255 Margin 68
HLSL 339 MarkerReached 197
Hojas de estilo 290, 317 MediaElement 48, 188, 216
HTA 83 MediaOpened 198
HTML dinmico 15 Moonlight 330
HTML 290 MouseMove 209
HtmlDocument 292
HtmlPage 300, 323 N
HtmlWindow 305, 310, 323 Name 57
HttpHandler 234 NavigateUri 113
HyperlinkButton 113 Nodo 83
NoWrap 128
I
IHttpHandler 236 O
IIS 270 OnClick 321, 325
Image 105, 114, 123, 215, 222 Onerror 57
InkPresenter 208, 225 OneTime 280
InnerHTML 295 OneWay 280
INPUT 297 OnExit 43
IntelliSense 61, 70 OnStartup 43
Interactividad 31 OpenFileDialog 251, 254
IsEnabledChanged 84
IsolatedStorageFile 240 P
IsolatedStorageFileStream 240 Param 57
IsolatedStorageSettings 240 Password 131
PasswordBox 130
J PasswordChar 131
JavaScript 290, 320 Pincel 211
Juego 222 Pixel Shader 338
Plantillas 58, 64, 178, 182
K Plugin 56
KeyDown 84 PointAnimation 171
KeyUp 84 PopupWindow 308

343
11_Silverlight_servicios.qxp 9/30/09 1:39 PM Page 344

SERVICIOS AL LECTOR

Position 190 TextWrapping 128


ProgressBar 148, 258 Threads 255
Punto de interrupcin 62 TimelineMarker 198
Timer 149, 256
R Transformaciones 45, 158, 175
RadioButton 110, 123 TransformGroup 158
Rotacin 161 Traslacin 159
RSS 230 Trazado 218
T-SQL 74
S TwoWay 280
ScaleTransform 165
ScriptObject 324 U
ScrollViewer 98 Uri 225, 231, 238
SDK 58 URL 230
Seguridad 239, 263 Usabilidad 31
SelectedItem 119
SelectionMode 140, 146 V
Servicios web 222 Validadores 281
SetAttribute 295 Video 194
SetProperty 317 VideoBrush 195
SetStyleAttribute 320 Visual Studio 24
ShowDialog 251
Slider 152, 191 W
SOA 19 WCF 21, 239, 270
SOAP 265 Web.Config 234, 271
Sonido 188 WebClient 230
Source 50 WebMethod 264
SourceName 196 Width 39, 85, 138, 302
StackPanel 95, 168, 181, 237 WMA 188
Storyboard 173, 256 WMV 194
Streaming 21, 188, 228 WPF 16, 37, 82
String 281
Stroke 213 X
Subnodo 83 XAML 16, 18, 21, 82, 148
XamlReader 238
T XAP 114
Tag 23, 82 XLinQ 230
Text 126, 183 XML 15, 22, 82
TextBlock 24, 61, 120, 126, 153, 183, 236
TextBox 41, 67, 127 Z
TextBoxStyle 45 Zoom 207

344
11_Silverlight_servicios.qxp 9/30/09 1:39 PM Page 345

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 reco-
mendable 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
11_Silverlight_servicios.qxp 9/30/09 1:39 PM Page 346

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 de-
sarrollos. No debemos olvidarnos de visitar la sala de videos educativos del sitio.

346
11_Silverlight_servicios.qxp 9/30/09 1:39 PM Page 347

Sitios web recomendados

ComponentArt
www.componentart.com
Compaa que provee controles y componentes de alta calidad para usar en el de-
sarrollo 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 desa-
rrollo de aplicaciones. Presenta un gran abanico de controles para Silverlight listos pa-
ra usar. De igual forma que el sitio anterior, estos componentes y controles son pagos.

347
11_Silverlight_servicios.qxp 9/30/09 1:39 PM Page 348

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 referen-
cia a todas las clases, mtodos, funciones, controles y componentes de Silverlight. Si te-
nemos alguna duda sobre el desarrollo para Silverlight, es necesario acudir a este sitio.

348
Catalogo_200RespRedes.qxd 11/21/08 2:21 PM Page 381

Claves para comprar un libro


de computacin.

1 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.

2 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.

3 Compare precios

Suele haber grandes diferencias de precio


entre libros del mismo tema; si no tiene el usershop.redusers.com
valor en la tapa, pregunte y compare.
Visite nuestro sitio web
4 ?Tiene valores agregados?
Utilice nuestro sitio usershop.redusers.com:
Desde un sitio exclusivo en la Red hasta
un CD-ROM, desde un Servicio de Atencin Vea informacin ms detallada sobre cada libro de este catlogo.
al Lector hasta la posibilidad de leer el Obtenga un captulo gratuito para evaluar la posible compra
sumario en la Web para evaluar con
tranquilidad la compra, o la presencia de de un ejemplar.
adecuados ndices temticos, todo suma al Conozca qu opinaron otros lectores.
valor de un buen libro.
Compre los libros sin moverse de su casa y con importantes
descuentos.
5 Verifique el idioma
Publique su comentario sobre el libro que ley.
No slo el del texto; tambin revise que las
Mantngase informado acerca de las ltimas novedades y los
pantallas incluidas en el libro estn en el
mismo idioma del programa que usted utiliza. prximos lanzamientos.

Tambin puede conseguir nuestros libros en kioscos o


6 Revise la fecha de publicacin
puestos de peridicos, libreras, cadenas comerciales,
Est en letra pequea en las primeras
pginas; si es un libro traducido, la que vale
supermercados y casas de computacin.
es la fecha de la edicin original.

Compra Directa! 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
Untitled-1 1 10/08/2009 12:28:30
Untitled-1 1 10/08/2009 12:37:19
Untitled-1 1 10/08/2009 12:56:13
RCT_Bombo_LIBROSilverlight.qxp 21/09/2009 16:10 Pgina 3

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
tapa Silverlight.qxp 21/09/2009 11:07 a.m. Pgina 1

SILVERLIGHT
DESCUBRA UN NUEVO NIVEL EN EL DESARROLLO
CONTENIDO DE APLICACIONES PARA INTERNET
1 | INTRODUCCIN A SILVERLIGHT Desde su lanzamiento, Silverlight se convirti rpidamente en la
Experiencia de usuario y portabilidad | Arquitectura de
Silverlight 2 | Microsoft .NET Framework | Interfaz de usuario opcin multiplataforma ideal, tanto para desarrollar aplicaciones
y presentacin | El cdigo XAML | Herramientas de desarrollo
enriquecidas e interactivas, como para generar experiencias
2 | MICROSOFT EXPRESSION BLEND 2 multimedia de vanguardia. Quien consiga dominarlo podr ofrecer a
Silverlight con Expression Blend | Explorador de soluciones |
Entorno | Barra de herramientas | Crear nuestra primera sus clientes aplicaciones visualmente impresionantes, tiempos de
aplicacin respuesta sin comparacin y requerimientos mnimos de ancho de
3 | SILVERLIGHT PARA DESARROLLADORES banda, todas ventajas acordes a los tiempos de la incipiente Web 3.0.
Puesta a punto de Visual Studio 2008 | Crear la primera
aplicacin | Interoperabilidad con Expression Blend 2
Esta obra ofrece un acercamiento profundo y prctico a esta
herramienta, y est dirigida a desarrolladores con conocimiento
4 | XAML AL EXTREMO
El lenguaje XAML | Declaracin de objetos | Controles y de Microsoft .NET Framework, que deseen profundizar en el desa-
componentes | Grid | GridSplitter | Canvas | StackPanel | rrollo Web. La enorme experiencia de Matas Iacono como desa-
ScrollViewer | Border | Controles de iteracin con el usuario |
Button | CheckBox | RadioButton | HyperlinkButton | Image | rrollador en esta plataforma lo convierte en el gua ideal para
ComboBox | ListBox | TextBlock | TextBox | PasswordBox |
DataGrid | Calendar | DatePicker | ProgressBar | Slider
aportar consejos prcticos bien fundados, ejemplos enriquecedo-
res y cdigo optimizado para aplicar en sus propios proyectos.
5 | LUZ, CMARA, ACCIN
Mover objetos | Transformaciones de traslacin, rotacin,
escalar y distorsin | Animaciones | DoubleAnimation |
ColorAnimation | Estilos y plantillas redusers.com
En este sitio encontrar una gran variedad de recursos y software relacionado,
6 | CERRAR EL CRCULO que le servirn como complemento al contenido del libro. Adems, tendr la po-
MediaElement | Ejecutar sonidos | Elementos con video sibilidad de estar en contacto con los editores, y de participar del foro de lecto-
embebido | Deep Zoom | Dibujar con InkPresenter | reas
de dibujo
res, en donde podr intercambiar opiniones y experiencias.

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


SILVERLIGHT
Silverlight is the cross-platform, cross-browser plug-in
for rich interactive applications and cutting-edge
NIVEL DE USUARIO media experiences. With advanced tips from our
expert, this book provides practical, grounded advice,
PRINCIPIANTE INTERMEDIO AVANZADO EXPERTO and rich examples, to be ready for todays challenges. por MATAS IACONO

También podría gustarte