Versión imprimible       Enviar     
Evaluar y enviar comentarios
Related Articles

En este artículo, describiremos algunos de los procedimientos recomendados para enlace y carga de ensamblados usando CLR.

Aarthi Ramamurthy y Mark Miller

MSDN Magazine Mayo 2009

...

Read more!

Participe de una conversación entre un programador y un profesional de seguridad que trata sobre algunos de los principales requisitos en el Ciclo de vida de desarrollo de seguridad (SDL, Security Development Lifecycle) que imponemos a los equipos de productos aquí en Microsoft.

Michael Howard

MSDN Magazine Mayo 2009

...

Read more!

Use el Desarrollo controlado por pruebas con objetos ficticios para diseñar código orientado a objetos en términos de funciones y responsabilidades, no de categorización de objetos en jerarquías de clases.

Isaiah Perumalla

MSDN Magazine Junio 2009

...

Read more!

Cobra, descendiente de Python, ofrece un modelo de programación dinámico, combinado y escrito en forma de estadística, funciones integradas de prueba unitaria, capacidades de scripting y mucho más. Sienta el poder aquí.

Ted Neward

MSDN Magazine Junio 2009

...

Read more!

Jeremy Miller continúa su análisis de los patrones de persistencia al revisar el patrón de diseño de la unidad de trabajo y examina los problemas en torno a la ignorancia de la persistencia.

Jeremy Miller

MSDN Magazine Junio 2009

...

Read more!

Also by this Author

Laurence Moroney muestra cómo emplear las API del complemento Expression Encoder creando y depurando un complemento sencillo de carga FTP.

Laurence Moroney

MSDN Magazine February 2008

...

Read more!

Popular Articles

Ray Djajadinata

MSDN Magazine May 2007

...

Read more!

James Avery does it again with his popular list of developer tools. This time he covers the best Visual Studio add-ins available today that you can download for free.

James Avery

MSDN Magazine December 2005

...

Read more!

Kenny Kerr alaba el nuevo Feature Pack de Visual C++ 2008, que incluye las comodidades actuales en Visual C++.

Kenny Kerr

MSDN Magazine May 2008

...

Read more!

C# allows developers to embed XML comments into their source files-a useful facility, especially when more than one programmer is working on the same code. The C# parser can expand these XML tags to provide additional information and export them to an external document for further processing. This article shows how to use XML comments and explains the relevant tags. The author demonstrates how to set up your project to export your XML comments into convenient documentation for the benefit of other developers. He also shows how to use comments ...

Read more!

Paul DiLascia

MSDN Magazine August 2002

...

Read more!

SILVERLIGHT
Empiece a disfrutar aún más navegando por la Web
Laurence Moroney

Este artículo se basa en una versión preliminar de Silverlight. Por tanto, es necesario tener en cuenta que toda la información de este documento está sujeta a cambios.
En este artículo se analizan los siguientes temas:
  • Introducción a Silverlight y XAML
  • Creación de una aplicación Silverlight sencilla
  • Generación dinámica de aplicaciones Silverlight en el servidor
  • Creación de un servicio XAML
En este artículo se utilizan las siguientes tecnologías:
Silverlight, XAML, JavaScript
Descargar el código de este artículo: Silverlight2007_06.exe (300 KB)
Examinar el código en línea
Un componente clave en la estrategia de Microsoft para el desarrollo web de siguiente generación es una tecnología nueva llamada Microsoft® Silverlight™, que anteriormente se denominaba con el nombre en código "WPF/E". Diseñada para llevar a la Web la experiencia de Windows® Presentation Foundation, Silverlight ofrece un amplio contenido enriquecido que es uniforme con el resto del entorno de desarrollo web, incluido ASP.NET AJAX.
Para alcanzar a la mayoría de la comunidad web, Silverlight necesita ejecutarse correctamente en diversos sistemas operativos conocidos y en los exploradores más usados. Como resultado, la primera versión es compatible con los exploradores Firefox y Safari que se ejecutan en Mac OS X, así como en Firefox y en Internet Explorer® ejecutándose en Windows. A medida que evolucione el producto, se irán admitiendo más sistemas operativos y exploradores. Además de estas capacidades, Silverlight también es completamente independiente y no depende de otros productos tales como Windows Media® Player para la reproducción de vídeo ni de Microsoft .NET Framework 3.0 para el análisis de XAML.
En este artículo, obtendrá una introducción general sobre la arquitectura de Silverlight y experiencia práctica para crear varias aplicaciones Silverlight, empezando por una aplicación básica de tipo Hello World. Luego le guiaré por el proceso de crear un reproductor de medios sencillo. También verá como, aunque Silverlight es una tecnología del lado cliente, encaja en una estrategia mayor orientada a servidor, incluida la capacidad de usarse en servidores que ejecutan PHP o Java.

Presentación de Silverlight
Esencialmente, Silverlight es un complemento de explorador que representa XAML, exponiendo su modelo de objetos del documento (DOM) interno y el modelo de evento al explorador de manera traducible en secuencias de comandos. Así, un diseñador puede reunir un documento XAML que contenga gráficos, animaciones y escalas de tiempo y un desarrollador puede adjuntarlos al código de una página para implementar la funcionalidad. Dado que XAML se basa en XML, el documento que define la IU que se descarga al cliente se basa en texto y, por los tanto, no da problemas a motores de búsqueda ni firewalls. Además, XAML puede ensamblarse y emitirse en tiempo de ejecución mediante una aplicación de servidor, lo que no sólo ofrece una experiencia gráfica enriquecida, sino también una muy personalizable y dinámica.
En la figura 1 se muestra la estructura de una aplicación Silverlight sencilla, usando un archivo XAML estático que define su IU y JavaScript para el control de eventos. El explorador crea una instancia del complemento y, como la parte de este proceso, carga el archivo XAML. Los eventos de este archivo, tales como el clic de un botón, los captura el explorador y los procesa JavaScript. Cuando se expone el DOM del contenido Silverlight, el código JavaScript también puede actualizar dinámicamente dicho contenido, cambiando el estado del contenido representado.
Figura 1 Aplicación de ejemplo 
La arquitectura que admite la aplicación Silverlight se muestra en la figura 2. La interfaz de programación principal es la API de JavaScript DOM. Esto permite responder a eventos sucedidos dentro del XAML de Silverlight, por ejemplo, cuando el contenido ha terminado de cargarse o cuando se completa una animación. También puede llamar a métodos para manipular la presentación, por ejemplo, al iniciar una animación o al detener la reproducción de vídeo. Debajo de esto se encuentra el motor de análisis de XAML. El analizador crea el DOM de XAML en memoria que el núcleo de presentación usará y que controla la representación de los gráficos y las animaciones definidos por XAML. Además, el tiempo de ejecución contiene los códecs necesarios para la reproducción de contenido multimedia WMV, WMA y MP3.
Figura 2 Arquitectura de Silverlight 
Por último, el tiempo de ejecución contiene el núcleo de presentación, que administra el proceso de representación. Este tiempo de ejecución de presentación está integrado en un complemento de explorador que admite varias versiones de Windows así como Mac OS X, usando varios exploradores, tal como se mencionó anteriormente. El resultado es un motor independiente de representación de gráficos y medios que puede acoplarse al explorador y controlarse mediante JavaScript.

Introducción a XAML
XAML es un lenguaje basado en XML que puede usarse para definir activos gráficos, interfaces de usuario, comportamientos, animaciones, etc. Microsoft lo presentó como lenguaje de marcado usado en Windows Presentation Foundation, una tecnología orientada a escritorios que forma parte de .NET Framework 3.0. Se diseñó para ayudar a unir el trabajo de los diseñadores y los desarrolladores en la creación de aplicaciones.
Tradicionalmente, los diseñadores usaban una serie de herramientas y recursos para crear una aplicación y los desarrolladores usaban sus propias herramientas independientes. La discordancia entre conjuntos de herramientas podía afectar de forma negativa a la aplicación resultante. Microsoft presentó la nueva serie de herramientas Expresión, en especial Microsoft Expression® Design y Microsoft Expression Blend, para permitir que los profesionales del diseño reúnan elementos gráficos e interfaces de usuario respectivamente, expresando el resultado final como XAML, que después un desarrollador puede usar como base para generar una aplicación.
El XAML que usaba la primera versión de Silverlight difiere del usado por Windows Presentation Foundation en que el anterior es un subconjunto web del XAML completo disponible para el escritorio. Por lo tanto, si conoce el XAML de Windows Presentation Foundation, notará que faltan algunas cosas como la etiqueta <Windows>, recursos de página, enlace de datos y el enriquecido modelo de control.
En XAML los elementos se definen mediante etiquetas XML. En el nivel raíz de cada documento Silverlight, hay una etiqueta Canvas que define el espacio en el que se dibujarán los elementos de la IU. Esta etiqueta Canvas debe contener las declaraciones de espacio de nombres XML que necesita Silverlight.
<Canvas
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”>
</Canvas>
Una etiqueta Canvas puede tener uno o más elementos secundarios, incluidos elementos Canvas secundarios que pueden crear sus propios elementos secundarios. Los elementos secundarios de una etiqueta Canvas tienen posiciones relativas respecto a su elemento Canvas principal, no al elemento Canvas raíz. Esto es un ejemplo de un elemento Canvas que contiene un rectángulo situado a 25 píxeles de la esquina superior izquierda de su elemento principal.
<Canvas Width=”250” Height=”200”>
  <Rectangle Canvas.Top=”25” Canvas.Left=”25” 
       Width=”200” Height=”150” Fill=”Black” />
</Canvas>

Dentro de XAML
Silverlight XAML admite varias formas que pueden combinarse en objetos complejos. Las formas básicas admitidas son rectángulos, elipses, líneas, polígonos, polilíneas y rutas. La mayoría de ellos no necesita explicación. Las polilíneas permiten definir una serie de segmentos unidos. Las rutas permiten definir una ruta no lineal (como un garabato) a través del elemento Canvas.
Los pinceles determinan la forma en que se dibujan los objetos en la pantalla. Su contenido se pinta mediante la función de relleno y sus esquemas se dibujan con un trazo. Hay pinceles de color sólido, pinceles de degradado y pinceles de imagen. Los pinceles de color sólido se implementan usando un color fijo en el atributo de relleno (por ejemplo, Fill="Black" del ejemplo anterior) o mediante SolidColorBrush como propiedad adjunta, tal como se indica a continuación:
   <Rectangle Canvas.Top=”25” Canvas.Left=”25” 
          Width=”200” Height=”150”>
      <Rectangle.Fill>
         <SolidColorBrush Color=”Black” />
      </Rectangle.Fill>
   <Rectangle>
Los colores se pueden definir por su nombre (se admiten 141 colores con nombre) o por definición RGB hexadecimal.
Los pinceles de degradado se implementan al definir un intervalo de degradado y varios puntos de degradado a lo largo de un espacio normalizado. Por ejemplo, supongamos que desea que un degradado lineal vaya de derecha a izquierda cambiando de negro a blanco pasando por niveles de gris a medida que avanza. En ese caso, especificaría un punto de degradado en 0 (el principio de una línea normalizada) que es el negro y un punto de degradado en 1 (el final de una línea normalizada) que es el blanco. A continuación, Silverlight pintará el degradado automáticamente. Los degradados también se pueden pintar en espacios de dos dimensiones, con un rectángulo normalizado que defina el espacio (0,0 es superior izquierdo y 1,1 es inferior derecho). De este modo, para definir un rectángulo relleno con un degradado 2D con rojo en el superior izquierdo, negro en el inferior derecho y un degradado suave entre ellos, se usaría un XAML como este:
<Rectangle Width=”200” Height=”150” >
  <Rectangle.Fill>
    <LinearGradientBrush StartPoint=”0,0” EndPoint=”1,1”>
      <LinearGradientBrush.GradientStops>
        <GradientStop Color=”Red” Offset=”0” />
        <GradientStop Color=”Black” Offset=”1” />
      </LinearGradientBrush.GradientStops>
    </LinearGradientBrush>
  </Rectangle.Fill>
</Rectangle>
Los objetos también se pueden pintar con ImageBrushes y la imagen se recortará o estirará según sea necesario. Así, por ejemplo, puede especificar rellenar una elipse con un ImageBrush con XAML de esta forma:
<Ellipse Width=”200” Height=”75” >
  <Ellipse.Fill>
    <ImageBrush ImageSource=”http://.../logo.jpg” /> 
  </Ellipse.Fill>
</Ellipse>
El texto se puede representar en XAML con la etiqueta TextBlock. Esto ofrece el control sobre aspectos del texto como, por ejemplo, el contenido, el tipo de letra, el tamaño, el ajuste, etc. Estos son algunos ejemplos:
<TextBlock>Hello</TextBlock>

<TextBlock FontSize=”18”>Hello</TextBlock>

<TextBlock FontFamily=”Courier New”>Hello</TextBlock>

<TextBlock TextWrapping=”Wrap” Width=”100”>
  Hello there, how are you?
</TextBlock>
Además, Silverlight admite eventos de teclado que se pueden usar para implementar la entrada de texto. Puede definir un evento de teclado (KeyDown o KeyUp) en el elemento raíz y usar los argumentos de evento para averiguar qué tecla se presionó.

Transformaciones, medios y animaciones
XAML permite definir varias transformaciones en objetos. RotationTransform gira el elemento un número definido de grados, ScaleTransform puede usarse para estirar o reducir un objeto, SkewTransform lo sesga en una dirección por una cantidad definida, TranslateTransform mueve un objeto según un vector definido y MatrixTransform puede combinar todo lo anterior.
Las transformaciones se pueden agrupar para que un objeto contenga varias de ellas si se definen esas transformaciones como parte del grupo. En la figura 3 se muestra un ejemplo. En este caso, hay tres elipses en el elemento Canvas. Dado que la transformación se define en el nivel de Canvas, cada una de estas elipses se girará y escalará.
<Canvas xmlns=”...” xmlns:x=”...”>
  <Canvas.RenderTransform>
    <TransformGroup>
      <RotateTransform Angle=”-45” CenterX=”50” CenterY=”50”/>
      <ScaleTransform ScaleX=”1.5” ScaleY=”2” />
    </TransformGroup>
  </Canvas.RenderTransform>
  <Ellipse Width=”100” Height=”100” Fill=”Yellow” />
  <Ellipse Canvas.Top=”25” Canvas.Left=”25” Width=”10” Height=”10” 
           Fill=”Black” />
  <Ellipse Canvas.Top=”25” Canvas.Left=”65” Width=”10” Height=”10” 
           Fill=”Black” />
</Canvas>
El contenido de audio y vídeo se controla con la etiqueta MediaElement. Esta etiqueta toma un atributo de origen que señala al medio que se debe reproducir. Un objeto definido con esta etiqueta ofrece muchos métodos y eventos que controlan la reproducción de medios. Más adelante en este artículo, verá un ejemplo de un reproductor de medios sencillo que se crea mediante XAML, con JavaScript que habilita la interacción con el usuario (reproducción, pausa, detención, etc.). La definición de un MediaElement es sencilla:
<Canvas xmlns=”...” xmlns:x=”...”>
   <MediaElement Source=”xbox.wmv” /> 
</Canvas>
Las animaciones en XAML se implementan al definir cómo deberían cambiar las propiedades a lo largo de una escala de tiempo. Las definiciones de animación se contienen en un guión gráfico. Hay varios tipos diferentes de animación, incluyendo DoubleAnimation, que cambia las propiedades numéricas; ColorAnimation, que cambia los colores y pinceles; y PointAnimation, que cambia valores bidimensionales. Estas animaciones pueden ser lineales o basadas en cuadros clave. En el caso de una animación lineal, ésta cambia suavemente a lo largo de la escala de tiempo definida. Con una animación basada en cuadros clave, ésta se puede mover libremente entre valores discretos.
La figura 4 muestra un ejemplo de animación sencilla que cambia el ancho de un círculo a lo largo del tiempo. La propiedad AutoReverse se establece en True, para indicar al motor que continúe la animación, invirtiéndola para que el círculo vaya de ancho a estrecho en vez de repetir una transformación de estrecho a ancho.
<Canvas xmlns=”...” xmlns:x=”...”>
  <Canvas.Triggers>
    <EventTrigger RoutedEvent=”Canvas.Loaded”>
      <BeginStoryboard>
        <Storyboard> 
          <DoubleAnimation 
            Storyboard.TargetName=”theCircle” 
            Storyboard.TargetProperty=”Width” 
            From=”200” To=”1” Duration=”0:0:2”        
            AutoReverse=”True”/>
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Canvas.Triggers>
  <Ellipse x:Name=”theCircle” Width=”100” Height=”100” Fill=”Yellow” />
</Canvas>

Una aplicación Silverlight sencilla
Con Visual Studio 2005, puede usar una plantilla de aplicación para Silverlight (parte de la descarga del SDK de Silverlight) que permite generar fácilmente aplicaciones para Silverlight. Para este artículo, usé la aplicación Visual Web Developer™ Express, que está disponible para su descarga desde MSDN®.
Este ejemplo es un reproductor de medios muy sencillo que reproduce contenido de vídeo WMV. Usa un vídeo de Channel 9 (channel9.msdn.com), pero puede cambiarlo para que reproduzca el vídeo que prefiera. Su XAML es bastante sencillo y se puede ver completamente en la figura 5. Para simplificarlo, se usan elementos TextBlock para los botones de reproducción, detención y pausa.
<Canvas 
    xmlns=”http://schemas.microsoft.com/client/2007”
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
    Loaded=”javascript:root_Loaded”>

    <MediaElement 
        x:Name=”mPlayer” Width=”640” Height=”400” 
        Source=”http://download.microsoft.com/download/6/5/2/6527a090-aef4-4ed2-8d7e-8946e94257a0/WM_IN_Sumit_Chauhan.wmv” />

    <TextBlock Canvas.Top =”0” Text=”Play” 
        MouseLeftButtonDown=”javascript:PlayVideo”>
    </TextBlock>
    <TextBlock Canvas.Top =”16” Text=”Stop” 
        MouseLeftButtonDown=”javascript:StopVideo”>
    </TextBlock>
    <TextBlock Canvas.Top =”32” Text=”Pause” 
        MouseLeftButtonDown=”javascript:PauseVideo”>
    </TextBlock>
</Canvas>
La etiqueta MediaElement se usa para definir el vídeo. Se le da un nombre, mPlayer, y sus dimensiones se establecen en 640×400. La etiqueta Source señala a un vídeo WMV que se aloja como descarga en el sitio web de Microsoft.
A continuación, están los tres elementos TextBlock que se usan para definir los botones de reproducción, detención y pausa. Estos botones se espacian verticalmente en el lado superior izquierdo del panel. Tenga en cuenta que no se establece Canvas.Left y su valor predeterminado es 0. Estos elementos TextBlock definen un controlador de eventos de JavaScript que se acciona cuando se hace clic en ellos (MouseLeftButtonDown). Cuando se presiona el botón del mouse sobre ellos, Silverlight pasa el evento al explorador, donde JavaScript lo captura y controla.
Ahora crearemos una aplicación que usa este XAML e implementa los controladores de eventos de JavaScript con Visual Web Developer Express. Para que esto funcione, necesitará el archivo silverlight.js, que se puede obtener de la descarga SDK para Silverlight o de cualquier ejemplo de Silverlight del sitio de descarga de ejemplos de MSDN.
Cree un sitio web nuevo usando Visual Web Developer Express. Dentro del sitio, cree una carpeta llamada js y agréguele el archivo silverlight.js. Haga clic con el botón secundario en la carpeta \js y seleccione Agregar nuevo elemento. Seleccione Archivo de JScript en el cuadro de diálogo de nuevo archivo y llámelo eventhandlers.js.
A continuación, en explorador de soluciones haga clic con el botón secundario en el proyecto, seleccione Agregar nuevo elemento y cree un archivo XML nuevo llamado videoplayer.xaml. Rellénelo con el XAML que se muestra en la figura 5.
Por último, agregue una página HTML nueva al proyecto y llámela Default.htm. Modifique la página HTML para que cargue las bibliotecas de JavaScript y las use para crear una instancia del reproductor Silverlight que representará el contenido XAML. La figura 6 muestra el código de origen completo para Default.htm.
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” 
    “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml” >
<head>
    <title>Untitled Page</title>
    <script type=”text/javascript” src=”js/silverlight.js”></script>
    <script type=”text/javascript” src=”js/eventhandlers.js”></script>
</head>
<body>
    <form>
         <div id=”AgControl1Host” style=”background:#FFFFFF”>     
            <script type=”text/javascript”>
                Sys.Silverlight.createObjectEx(
                    {source: ‘videoplayer.xml’, 
                     parentElement:’AgControl1Host’, 
                     Id:’AgControl1’, 
                     properties:{
                         width:’1024’, 
                         height:’530’, 
                         background:’white’, 
                         isWindowless:’false’, 
                         framerate:’24’, 
                         version:’0.8.5’}, 
                     events:{onError:null, onLoad:null, 
                         onNotInstalled:null}, 
                     context:null});
            </script>
         </div>
    </form>
</body>
</html>
Las etiquetas de secuencias de comandos de la parte superior de la página importan las bibliotecas JavaScript, silverlight.js y eventhandlers.js. La biblioteca silverlight.js administra la descarga y la creación de instancias del complemento Silverlight. Tiene las abstracciones del explorador y del sistema operativo, por lo que no necesita preocuparse por ellos; sólo necesita implementar un control nuevo de Silverlight con la función Sys.Silverlight.createObjectEx. El propio complemento de Silverlight debe estar dentro de un bloque DIV al que se le da una identificación. En este caso, el DIV que contiene el complemento se denomina AgControl1Host. Este Id. se usará al crear las instancias del contenido de Silverlight.
La creación de instancias del complemento de Silverlight se realiza mediante la creación de una instancia nueva del control de Silverlight, pasándole un conjunto de parámetros para su generación. Consulte el SDK de Silverlight para obtener más información acerca de estos parámetros.
El paso final es implementar las funciones de JavaScript que administran los eventos accionados al hacer clic en los botones de reproducción, detención y pausa. Este código debe colocarse en eventhandlers.js.
function PlayVideo(sender,args)
{
   var mPlayer = sender.findName(“mPlayer”);
   mPlayer.Play();
}
function PauseVideo(sender,args)
{
   var mPlayer = sender.findName(“mPlayer”);
   mPlayer.Pause();
}
function StopVideo(sender,args)
{
   var mPlayer = sender.findName(“mPlayer”);
   mPlayer.Stop();
}
En XAML, el TextBlock Stop definió el atributo MouseLeftButtonDown para que señale a JavaScript:StopVideo. La función se implementa al crear una función JavaScript del mismo nombre que toma los parámetros de remitente y argumentos. Puede usar la función findName en Silverlight para buscar un elemento dentro de su DOM que coincida con el parámetro denominado. Por lo tanto, para detener la reproducción del vídeo, se usa la API findName para buscar el MediaElement. En XAML, este elemento se denominó mPlayer. La API findName devolverá una referencia a este objeto que puede cargar en una variable JavaScript. Ahora que tiene una referencia, sólo tiene que llamar a su método Stop para detener la reproducción del vídeo. Las funcionalidades de reproducir y pausa son parecidas.
¡Y eso es todo! Un reproductor de vídeo sencillo creado con Silverlight en un instante. Ejecute su aplicación y verá algo parecido a la figura 7.
Figura 7 Reproductor de vídeo sencillo (Hacer clic en la imagen para ampliarla)
Todo esto está muy bien si desea fijar el URI del vídeo en el XAML, pero realmente no es el caso de uso más factible. Procuremos ahora cambiar esto de una página HTML estática a un formulario web activo que pueda aceptar el vídeo como parámetro.
El primer paso es quitar la referencia al archivo de medios desde XAML. Cambie el MediaElement del XAML para quitar el atributo Source. Cuando haya terminado, debe parecerse a esto:
<MediaElement x:Name=”mPlayer” Width=”640” Height=”400”/>
A continuación, cree un formulario web (ASPX) nuevo llamado Videoplayer.aspx en la aplicación. Este formulario debe crear una instancia de un control Silverlight originado en videoplayer.xaml, tal como se hizo en la figura 6. También debe contener el código JavaScript siguiente:
<script type=”text/javascript”>
  function root_Loaded(sender,args) {
    var mPlayer = sender.findName(“mPlayer”);
    mPlayer.Source =
      “<% Response.Write(Request.Params[“VideoURI”]); %>”;
    mPlayer.Play();
}
</script>
El XAML contiene una declaración de evento para que el evento se accione cuando se cargue el elemento Canvas. Esto lo captura el controlador de eventos root_Loaded en JavaScript. Esta función usa ASP.NET para extraer VideoURI de la solicitud HTTP en el servidor y usa VideoURI para completar la función de JavaScript, estableciendo así el origen del video. Cuando se ejecute la página, Silverlight representará el vídeo (en el parámetro VideoURI). Tenga en cuenta que este ejemplo muy sencillo no tiene ningún control de errores ni filtrado, que se debería agregar si desea este tipo de funcionalidad en las aplicaciones.
Tenga en cuenta que cuando se llama a esta página con un URI como este:
http://localhost/MSDN1/
VideoPlayer.aspx?videouri=xbox.wmv
ASP.NET emitirá una página que contiene un bloque JavaScript parecido a este:
   <script type=”text/javascript”>
     function root_Loaded(sender,args)
     {
       var mPlayer = 
         sender.findName(“mPlayer”);
       mPlayer.Source = “xbox.wmv”;
       mPlayer.Play();
     }
   </script>
A continuación, este JavaScript carga el archivo xbox.wmv en MediaElement y Silverlight reproduce el vídeo. Esto demuestra que usar páginas activas del lado del servidor (ASPX, PHP o Java) puede mejorar mucho la experiencia del usuario final de Silverlight haciéndolas mucho más flexibles.

Aplicaciones de servidor con Silverlight
No es muy correcto pensar en Silverlight sólo como una tecnología cliente pensada para incrustar contenido enriquecido en el explorador. Este tipo de contenido enriquecido ya es posible mediante el uso de complementos cerrados generados como subprogramas de Java, controles ActiveX® o aplicaciones Flash. En cambio, Silverlight es una tecnología abierta en el sentido que la IU se define en XAML basado en texto y la capacidad de programación se consigue con JavaScript. Esto permite a los desarrolladores generar fácilmente aplicaciones que interactúan con servidores back-end.
Por ejemplo, consideremos una aplicación meteorológica. Si deseara producir una aplicación meteorológica en el cliente, podría generar un subprograma de Java, un control ActiveX o una aplicación Flash que usase un servicio web y después implementar este subprograma en el cliente. Sin embargo, esto aumentaría las necesidades de comunicación entre el cliente y el servidor. ¿Qué sucede si este origen de datos es un servicio de suscripción de pago? La persona que implementa la aplicación tiene que encargarse de autenticar las licencias de todos los clientes que obtienen acceso al servicio de datos y eso quita tiempo para crear lógica empresarial específica del dominio.
Sin embargo, si la aplicación se puede ensamblar en el servidor y todos los datos se pueden volver a pasar al cliente, entonces se reducirá la carga de trabajo. Al usar una herramienta como Expression Blend, se puede ensamblar una plantilla para la interfaz de usuario de la aplicación y expresarla como XAML. A continuación, el desarrollador, en tiempo de ejecución, toma los datos pertinentes y los inserta en la plantilla, devolviendo el XAML terminado al cliente que lo representa. No se requiere ninguna lógica ni conectividad en el cliente (aparte de la conectividad inicial con el servidor que lo sirve, por supuesto) y la implementación y administración del cliente se mantienen relativamente sencillas.

Creación de una aplicación meteorológica
En esta sección, verá cómo generar un archivo XAML sencillo que implementa una aplicación meteorológica (consulte la figura 8). La aplicación meteorológica terminada representará el pronóstico de las temperaturas de tres días para un código postal específico que se pasa a la aplicación como parámetro en la dirección dentro del explorador. También generará una representación gráfica del tiempo, las fechas correctas, el nombre de la ubicación especificada por el código postal y animaciones de los datos meteorológicos. La lista completa del XAML para la aplicación meteorológica está disponible en el sitio web de MSDN Magazine.
Figura 8 Aplicación meteorológica de Silverlight (Hacer clic en la imagen para ampliarla)
Al principio del documento se encuentra la etiqueta de apertura Canvas. Se trata de un contenedor básico en el que se dibujarán los objetos. No está limitado a una única etiqueta Canvas y tiene sentido agrupar todos los elementos relacionados usando un elemento Canvas. Así, por ejemplo, cada día contiene un gráfico, una temperatura máxima, una temperatura mínima y varias etiquetas, y todo esto se reúne en una plantilla de XAML. La figura 9 es un ejemplo de un día concreto. En este caso, el elemento Canvas contiene diversos TextBlocks y un control Image. A este elemento Canvas se le asigna el nombre cnv2 y se coloca en pantalla con una opacidad de 0 (lo que significa que inicialmente no es visible). Su altura, ancho, margen izquierdo y superior se establecen para situarlo en una ubicación específica en la pantalla.
<Canvas x:Name=”cnv2” Width=”624” Height=”101” Opacity=”0” 
        Canvas.Left=”8” Canvas.Top=”165”>

<TextBlock x:Name=”lblDate2” Width=”513” Height=”26” Canvas.Left=”97” FontFamily=”Tahoma” FontSize=”20” FontWeight=”Bold” Foreground=”#FF24AB46” Text=”Wednesday, December 18, 2006” TextWrapping=”Wrap”/>

<TextBlock x:Name=”lblHigh2” Width=”70” Height=”59” Canvas.Left=”112” Canvas.Top=”30” FontFamily=”Tahoma” FontSize=”48” FontWeight=”Bold” Foreground=”#FFF64F12” Text=”27” TextWrapping=”Wrap”/>

<TextBlock x:Name=”lblDegHigh2” Width=”62” Height=”59” FontFamily=”Tahoma” FontSize=”48” FontWeight=”Bold” Foreground=”#FFF64F12” Text=”°F” TextWrapping=”Wrap” Canvas.Left=”172” Canvas.Top=”30”/>

<TextBlock x:Name=”lblLow2” Width=”71” Height=”59” FontFamily=”Tahoma” FontSize=”48” FontWeight=”Bold” Foreground=”#FF444DB5” Text=”27” TextWrapping=”Wrap” Canvas.Left=”265” Canvas.Top=”30”/>

<TextBlock x:Name=”lblDegLow2” Width=”67” Height=”59” FontFamily=”Tahoma” FontSize=”48” FontWeight=”Bold” Foreground=”#FF444DB5” Text=”°F” TextWrapping=”Wrap” Canvas.Left=”327” Canvas.Top=”30”/>

<Image x:Name=”imgWeather2” Width=”97” Height=”87” Canvas.Top=”4” Source=”http://www.nws.noaa.gov/weather/images/fcicons/ra80.jpg” Stretch=”Uniform”/>

</Canvas>
Los TextBlocks se usan para representar texto en Silverlight. Aquí hay varios, algunos se usan como etiquetas codificadas, tales como las de "°F" que se almacenan en los TextBlocks llamados lblDegHigh2 y lblDegLow2. Consulte el atributo x:Name para buscar el nombre.
Los TextBlock llamados lblDate2, lblHigh2 y lblLow2 contienen información de marcador de posición; en este momento están codificados para datos y temperatura específicos, pero el código ASP.NET los reemplazará con la fecha y las temperaturas reales para el código postal especificado.

Definición de animaciones fundidas
Un nodo Canvas admite desencadenadores que activan acciones en respuesta a un evento. En este caso, se especifica que Canvas.Triggers se produzca cuando se cargue la página, tal como se muestra aquí:
<Canvas.Triggers>
  <EventTrigger RoutedEvent=”FrameworkElement.Loaded”>
    <BeginStoryboard>
...
De este modo, cuando se cargue la página, los desencadenantes se activarán y se iniciará un guión gráfico de animación. El guión gráfico de animación define los comportamientos de la animación. Aquí está la animación que se usa en el elemento Canvas (que contiene los marcadores de posición de texto y los gráficos para el tiempo específico de día) llamado cnv1:
<DoubleAnimationUsingKeyFrames BeginTime=”00:00:00”  
    Storyboard.TargetName=”cnv1” 
    Storyboard.TargetProperty=”(UIElement.Opacity)”>
  <SplineDoubleKeyFrame KeyTime=”00:00:00” Value=”0”/>
  <SplineDoubleKeyFrame KeyTime=”00:00:01” Value=”1”/>
</DoubleAnimationUsingKeyFrames>
El tipo de animación es DoubleAnimationUsingKeyFrames. Ahora modificará la opacidad (definida por UIElement.Opacity) del elemento Canvas y sus elementos secundarios de 0 a 1, haciendo que aparezca progresivamente en un espacio de tiempo. El tiempo lo definen los cuadros clave asociados a la animación.
Cuando XAML genera la representación, empezará el guión gráfico, haciendo que el primer elemento aparezca progresivamente de desde la opacidad 0 a la opacidad 1 entre el principio de la representación (tiempo de 0 segundos) hasta 1 segundo más tarde. Observe el XAML y verá que los demás elementos Canvas aparecen progresivamente entre 1 y 2 segundos, y entre 2 y 3 segundos respectivamente, creando el efecto de que aparecen en sucesión.
XAML es una forma de XML válido, por lo que los elementos se pueden denominar con atributos y pueden direccionarse a partir de esa denominación. Así, por ejemplo, el elemento de marcador de posición para la temperatura máxima del día 1 tiene el aspecto siguiente:
<TextBlock x:Name=”lblHigh1” Width=”67” Height=”59” 
        Canvas.Left=”112” Canvas.Top=”30” FontFamily=”Tahoma” 
        FontSize=”48” FontWeight=”Bold” Foreground=”#FFF64F12” 
        Text=”27” TextWrapping=”Wrap”/>
A este TextBlock se le asigna el nombre lblHigh1. El servicio (que verá en el paso siguiente) usa un XMLDocument para cargar la plantilla XAML, encontrar el nodo con este nombre y cambiar su propiedad de texto con código C# parecido a este:
string xpath = “//d:TextBlock[@x:Name=’lblHigh1’]”;
xNode = xmlDoc.SelectSingleNode(xpath, mng);
string high = myResults[n - 1].MaxTemperatureF;
xNode.Attributes[“Text”].Value = high;

Creación de un servicio XAML
Al usar Silverlight en una página web, uno de los parámetros que toma el control es la ubicación del XAML que se debe representar. En este caso, XAML es dinámico y los cambios se basan en el código postal para el que se solicita la meteorología. Por este motivo, se creará una aplicación web que genera y devuelve el XAML, y la página que lo representa hará referencia a esta página. Este es el primer paso en la generación de esta aplicación Silverlight.
Use Visual Studio® para crear un proyecto web nuevo. Agregue una carpeta \js que contenga silverlight.js, tal como hizo anteriormente con el reproductor de vídeo. Agregue una referencia web nueva al proyecto, haciendo referencia al servicio web definido en:
http://www.webservicex.net/WeatherForecast.asmx?WSDL
Asigne al servicio el nombre weatherservice. Agregue un formulario web nuevo al proyecto y llámelo XAMLSOURCE.aspx. Seleccione la opción de agregar código como página independiente. Asegúrese de que la parte superior de la página de código tenga el conjunto siguiente de directivas de uso:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Xml.XPath;
En el resto de esta sección, agregará código al controlador de eventos Page_Load en XAMLSOURCE.aspx. Primero, cargue la plantilla (llamada Scene.xaml) en un objeto XMLDocument:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(Server.MapPath(“Scene.xaml”));
A continuación, configure el parámetro de lectura. Llamará a la página con un parámetro de cadena de consulta que especifica el código postal necesario:
http://server/XamlSource.aspx?ZIP=<something>
Para recuperar el parámetro, use este código:
string strZip = “98052”;
if (Request.Params[“ZIP”] != null)
    strZip = Request.Params[“ZIP”];
Esto inicia la cadena que contendrá el código postal parametrizado de forma local y lo establecerá en un valor predeterminado si no se pasa como parte de la solicitud HTTP. A continuación, cree la llamada al servicio web que sirve la información meteorológica:
weatherservice.WeatherForecast myWeather = new 
    weatherservice.WeatherForecast();

weatherservice.WeatherForecasts myForecast =   
    myWeather.GetWeatherByZipCode(strZip);

weatherservice.WeatherData[] myResults = myForecast.Details;
Este código crea una instancia del proxy del servicio web (que ha creado Visual Studio para usted al agregar una referencia al WSDL del servicio) que denomina myWeather. El servicio web devuelve datos en la estructura de datos WeatherForecasts, de modo que crea una instancia de esta estructura de datos (denominada myForecast) al llamar al método GetWeatherByZipCode en el servicio, pasándole una cadena. El miembro Details del objeto del pronóstico es una matriz de tipos WeatherData, por lo que la variable myResults se establece como instancia de ello.
El paso siguiente es inicializar XMLDocument para buscar mediante XPath. Dado que XML usa el esquema XAML como espacio de nombres para algunos de los elementos (marcados con el prefijo x, como en x:Name), deberá definir un espacio de nombres para todos los elementos de la página, incluso los que no tienen prefijo. Por ejemplo, no puede buscar nodos que coincidan con XPath //TextBlock, pero puede especificar el espacio de nombres predeterminado para tener un prefijo nuevo (en este caso d como ficticio) y buscar los nodos predeterminados usando este prefijo, por lo que //d:TextBlock funcionará. Este es el código:
NameTable myn = new NameTable();
XmlNamespaceManager mng = new XmlNamespaceManager(new NameTable());
mng.AddNamespace(“d”,
    “http://schemas.microsoft.com/winfx/2006/xaml/presentation”);
mng.AddNamespace(“x”, “http://schemas.microsoft.com/winfx/2006/xaml”);
Ahora que puede usar XPath, puede buscar el nodo que contiene el nombre de la localidad y cambiar su propiedad Text para que coincida con la localidad que el servicio identificó en ese código postal.
XmlNode xNode = xmlDoc.SelectSingleNode(
    “//d:TextBlock[@x:Name=’lblTownName’]”, mng);

xNode.Attributes[“Text”].Value = 
    myForecast.PlaceName + “,” + myForecast.StateCode;
De forma similar, puede iniciar un bucle por los tres días siguientes, buscar los nodos de marcador de posición que contienen las ubicaciones deseadas para sus valores y recortar los valores correctos en el XML con el código que se muestra en la figura 10.
string strXPath = “”;
string strDate = “”;
string strHigh = “”;
string strLow = “”;
string strWeatherURL = “”;

for (int n = 1; n <= 3; n++)
{
  strXPath = “//d:TextBlock[@x:Name=’lblDate” + n.ToString() + “’]”;
  xNode = xmlDoc.SelectSingleNode(strXPath, mng);
  strDate = myResults[n - 1].Day;
  xNode.Attributes[“Text”].Value = strDate;

  strXPath = “//d:TextBlock[@x:Name=’lblHigh” + n.ToString() + “’]”;
  xNode = xmlDoc.SelectSingleNode(strXPath, mng);
  strHigh = myResults[n - 1].MaxTemperatureF;
  xNode.Attributes[“Text”].Value = strHigh;

  strXPath = “//d:TextBlock[@x:Name=’lblLow” + n.ToString() + “’]”;
  xNode = xmlDoc.SelectSingleNode(strXPath, mng);
  strLow = myResults[n - 1].MinTemperatureF;
  xNode.Attributes[“Text”].Value = strLow;

  strXPath = “//d:Image[@x:Name=’imgWeather” + n.ToString() + “’]”;
  xNode = xmlDoc.SelectSingleNode(strXPath, mng);
  strWeatherURL = myResults[n - 1].WeatherImage;
  xNode.Attributes[“Source”].Value = strWeatherURL;
}
Ahora que ha rellenado completamente el documento XML con la plantilla y los datos correctos, el último paso es devolverlo a quien inició la llamada. Esto se hace estableciendo el tipo MIME y escribiendo el del objeto XMLDocument directamente en el flujo de la respuesta, tal como se indica abajo:
Response.ContentType = “text/xml”;
Response.Write(xmlDoc.InnerXml);
A continuación, quite el HTML marcador proporcionado por Visual Studio en la página ASPX. Quite todo menos la primera línea del archivo de ASPX. Cuando haya terminado, su aspecto debe ser parecido al código siguiente:
<%@ Page Language=”C#” AutoEventWireup=”true”    
         CodeFile=”XamlSource.aspx.cs” Inherits=”_Default” %>
El paso final es agregar un archivo XML nuevo a la solución y llamarlo Scene.xaml. Habrá visto alguna referencia a este archivo en el código anteriormente. Obtenga el XAML del pronóstico del tiempo completo y péguelo en este archivo. Ahora puede ejecutar la página y debería ver el XAML devuelto por la página XAMLSource.aspx en el explorador.

Generación de XAML al cliente Silverlight
En los pasos anteriores, generó la plantilla XAML y después un formulario web que toma este XAML, consume un servicio web y pone los resultados de la llamada al servicio web en el lugar correcto del XAML. El paso siguiente es servir una página que contiene el control Silverlight y señala a este servicio de XAML.
Abra el sitio web que usó en las secciones anteriores y agregue un formulario web nuevo llamado Default.aspx. Modifique el código HTML de Default.aspx para que sea como el de la figura 11.
<%@ Page Language=”C#” AutoEventWireup=”true”
    CodeFile=”Default.aspx.cs” Inherits=”_Default” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
 “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
    <title>Weather</title>
    <meta http-equiv=’Content-Type’ 
          content=”text/html; charset=windows-1252”/>
    <script type=”text/javascript” src=”js/silverlight.js”></script>
</head>
<body>
<div id=”AgControl1Host” style=”background:#FFFFFF”>     
    <script type=”text/javascript”>
        Sys.Silverlight.createObjectEx(
            {source: ‘WeatherSite/XamlSource.aspx?ZIP=<%
                        if (Request.Params[“ZIP”] == null)
                            Response.Write(“98052”);
                        else
                           Response.Write(Request.Params[“ZIP”]);
              %>’, parentElement:’AgControl1Host’, Id:’AgControl1’, 
              properties:{width:’1024’, height:’530’, 
                  background:’white’, isWindowless:’false’, 
                  framerate:’24’, version:’0.8.5’}, 
              events:{onError:null, onLoad:null, onNotInstalled:null},
                  context:null});
    </script>
</div>
</body>
</html>
La parte importante de esto está en la llamada a Silverlight.createObjectEx, donde el videoplayer.xaml estático se ha sustituido por una llamada a la aplicación de origen XAML, pasándole el parámetro que recibió esta página Default.aspx como código postal:
“WeatherSite/XamlSource.aspx?ZIP=<%
    if (Request.Params[“ZIP”] == null)
        Response.Write(“98052”);
    else
        Response.Write(Request.Params[“ZIP”]);
%>” 
Esto lleva el parámetro de solicitud a esta página y lo anexa a una dirección URL, que llamará a la página XamlSource que creó en el último paso. A su vez, esto hará una llamada a XamlSource, pasando el código postal y obteniendo como respuesta un documento XAML, que entonces representa Silverlight. Los resultados de ejecutar Default.aspx?ZIP=90210 pueden verse en la figura 8.

Resumen
En este artículo se le ofreció una introducción completa a Silverlight. Pudo ver algunas aplicaciones que van más allá del consabido "Hello, World" como, por ejemplo, la forma en que XAML se usa para generar interfaces de usuario, cómo se puede enlazar con JavaScript para añadir capacidad interactiva y cómo puede ir más allá de un simple paradigma de cliente hasta uno basado en servidor para que las aplicaciones sean más flexibles. Mediante esta metodología, pudo ver cómo crear un reproductor de vídeo sencillo que acepta el URI de un flujo de vídeo y lo reproduce, lo que lo hace ideal para usarlo en situaciones como blogs.
También aprendió cómo generar una aplicación que tenga en cuenta datos, en forma de un control meteorológico que tiene un modelo de distribución cliente muy sencillo. Sólo tuvo que hacer que el componente Silverlight llamara al servidor para obtener el XAML correcto y representarlo formando un cliente enriquecido y fino.
Si bien ASP.NET y la pila de Microsoft representan una plataforma muy productiva para generar aplicaciones web como esta, la descarga de este artículo también contiene una versión Java de esta aplicación. Esta versión ofrece la misma funcionalidad que ASP.NET, consumiendo el servicio web para obtener los datos y después cargando el XAML en un DOM de documento XML. Luego recopila los nodos apropiados para los datos de plantilla y reemplaza sus valores por los del servicio web antes de escribir el XAML terminado en forma de URI. Entonces se construye el JSP (no mostrado) para que haga referencia a la dirección URL de este servlet para que represente el XAML mediante Silverlight.
El camino de Silverlight en la Web sólo acaba de empezar. Gracias a la riqueza de un motor de representación XAML y a la flexibilidad de usar tecnologías estándar del desarrollo web, Silverlight es algo que merece la pena añadir al conjunto de herramientas del desarrollador. Si desea obtener más información, consulte la Zona para desarrolladores en Silverlight en MSDN.

Laurence Moroney es un entusiasta de la tecnología Silverlight en Microsoft. Es autor de nueve libros de informática y más de 100 artículos sobre tecnología, incluido Programming Web.NEXT de Microsoft Press, que se presentará próximamente. Cuando no escribe artículos o código, normalmente vuelve loco al equipo del producto con preguntas acerca de la compatibilidad de las características en Silverlight.

Page view tracker