April 2009 - Posts

MSDN ha organizado para el 13 de Mayo un evento sobre Silverlight y Expression, donde se va a presentar la comunidad UXity, que será el punto de encuentro de todos aquellos que nos interesamos en la experiencia de usuario.

El evento constara de dos sesiones, una donde serán detallados algunas de las novedades de Silverlight 3 además de una introducción a la comunidad. En la segunda sesión se verá como utilizar las herramientas de Expression además de como integrar al equipo de diseño con el de desarrollo.

Estaré participando como orador en la primer sesión junto a Paulo Arancibia.

El evento será en Microsoft de Argentina y estará arrancando a las 18:30.

Para inscribirse pueden ir aquí.

Silverzine es un sitio dedicado a Silverlight pero orientado exclusivamente a diseñadores.

La idea es presentar tutoriales y recursos para que los usuarios puedan aprender, inspirarse o simplemente utilizar estos recursos para sus aplicaciones.

Pueden visitar el sitio aquí.

Webby People's Voice Awards es un premio internacional otorgado a lo mejor de internet, con sponsors como Adobe, Nokia, etc. Para este año, han elegido a Silverlight para el desarrollo de varias partes del sitio, como ser la votación y visualización de videos.

Pueden visualizar el sitio aquí. Tienen que registrase para poder ver los videos.

1

Voy a mostrar de que manera podemos crear nuestro lector de feeds de RSS 2.0 en Silverlight. Vamos a utilizar el namespace System.ServiceModel.Syndication que nos brinda todas las clases necesarias para interpretar estos archivos.

Vamos a crear una aplicación Silverlight desde Visual Studio, luego agregaremos las referencias a System.Windows.Controls.Data (ya que utilizaremos un DataGrid para visualizar la información) y System.ServiceModel.Syndication.

Agregamos los controles dentro del XAML, un TextBox donde vamos a poder escribir la URL que queremos cargar, un Button que dispara el evento para leer el feed y un DataGrid donde se muestra la información.

<Grid x:Name="LayoutRoot" Background="White">
 
    <Grid.RowDefinitions>
        <RowDefinition Height="30" />
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    
    <TextBox x:Name="txtRSS" 
             Width="550" Grid.Row="0" Grid.Column="0" 
             HorizontalAlignment="Left" ></TextBox>
    <Button x:Name="btnCargar" Grid.Row="0" Content="Cargar RSS" 
            Width="100" HorizontalAlignment="Left" Grid.Column="1"  
            Click="btnCargar_Click"></Button>
    
    <data:DataGrid x:Name="dgRSS" AutoGenerateColumns="False" 
                   IsReadOnly="True" CanUserSortColumns="True" 
                   Grid.Row="1" Grid.ColumnSpan="2">
        <data:DataGrid.Columns>
            <data:DataGridTemplateColumn>
                <data:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <HyperlinkButton Content="{Binding Titulo}" 
                                             NavigateUri="{Binding Link}" 
                                             TargetName="_blank"/>
                            <TextBlock Text="{Binding Descripcion}" 
                                       TextWrapping="Wrap" 
                                       UseLayoutRounding="True"/>
                        </StackPanel>
                    </DataTemplate>
                </data:DataGridTemplateColumn.CellTemplate>
            </data:DataGridTemplateColumn>
        </data:DataGrid.Columns>
    </data:DataGrid>
 
</Grid>

Ahora en el code-behind vamos a empezar agregando la clase RSSFeed, que representa cada ítem del feed que vamos a leer.

public class RSSFeed
{
    public string Titulo { get; set; }
    public string Link { get; set; }
    public string Descripcion { get; set; }
}

 

Ahora agregamos las referencias a las clases que vamos a utilizar.

using System.ServiceModel.Syndication;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Xml;

Agregamos ahora el handler del click del Button, donde vamos a llamar a la función que lee los feeds.

private void btnCargar_Click(object sender, RoutedEventArgs e)
{
    if (txtRSS.Text != String.Empty)
        CargarRSS(txtRSS.Text.Trim());
}
 
protected void CargarRSS(string uri)
{
    WebClient wc = new WebClient();
    wc.OpenReadCompleted += 
        new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
    Uri feedUri = new Uri(uri, UriKind.Absolute);
    wc.OpenReadAsync(feedUri);
}
 
private void wc_OpenReadCompleted(object sender,    
                                  OpenReadCompletedEventArgs e)
{
    if (e.Error != null)
    {
        txtRSS.Text = "Error al cargar el RSS. Intente nuevamente!!!";
        return;
    }
    using (Stream s = e.Result)
    {
        SyndicationFeed feed;
        
        using (XmlReader reader = XmlReader.Create(s))
        {
            feed = SyndicationFeed.Load(reader);
            var posts = from item in feed.Items
                        select new RSSFeed()
                        {
                            Titulo = item.Title.Text,
                            Link = item.Links[0].Uri.AbsoluteUri,
                            Descripcion = item.Summary.Text
                        };
            dgRSS.ItemsSource = posts;
            dgRSS.Visibility = Visibility.Visible;
        }
    }
}

Utilizamos WebClient para obtener la información del RSS. Como resultado obtenemos un XML, que la clase SyndicationFeed lo transforma en una colección de feeds, los cuales ya tienen las propiedades clásicas de un feed para que nosotros podamos usar, de esta manera de forma fácil podemos obtener estos datos sin tener que recorrer el XML nosotros mismos.

A este proyecto pueden agregarle estilos para ver mejor los feeds, además de pasar la URL por parámetro y no utilizando un TextBox.

1

Gran ejemplo de una aplicación desarrollada en Silverlight. Es una página alemana dedicada a la venta de bicicletas. Utilizan Deep Zoom para visualizar las misma, además de poder filtrar por precio o color.

1 Pueden visitar el sitio aquí.

Local Impact Map es un desarrollo de Microsoft hecho en Silverlight donde se muestran mas de 500 historias sobre el impacto positivo de distintos programas para la comunidad apoyados por Microsoft.

Lo interesante de esta aplicación, es las características que tiene:

  • El mapa de fondo esta realizado con Deep Zoom.
  • Soporte para agregar a favoritos y para el botón “Atras” del browse. Cada estado de la página puede ser marcado como favorito.
  • Posibilidad de generar “snapshots” para realizar presentaciones.
  • Búsqueda por todo el sitio.
  • Soporte de imágenes y videos.

Pueden visitar el sitio aquí.

1

4

Cuando utilizamos Visual Studio y agregamos o abrimos un XAML, por defecto vemos el código y el preview, por lo que se hace lento para los programadores ya que si tenemos un MediaElement, intenta cargarlo, haciendo algo tedioso esta operatoria.

Si queremos que siempre nos abra directamente en el código, vamos a tener que modificar una opción de Visual Studio.

Primero vamos a Herramientas y luego a Opciones. Luego ir a la opción Editor de Texto (tener en cuenta que tenemos que tener marcada la opción “Mostrar todas las propiedades”).

Dentro de esta opción vamos a XAML y luego a Misceláneas. En la parte derecha, vamos a ver que tenemos un check que nos dice si abrimos los XAML en vista completa. Le damos click al check y luego Aceptar.

De esta manera siempre que abramos un XAML, vamos a ver primero el código sin el preview.

Voy a mostrar de que manera podemos integrar los servicios de búsqueda de Live.com en una aplicación Silverlight utilizando Live Search API 2.0. Esta API nos permite realizar búsquedas de imágenes, páginas y demás tipos.

En el ejemplo vamos a ver como interactuar con la API, como obtener los resultados de búsqueda y como enlazarlos en un ListBox de Silverlight.

El primer paso es generar un API ID, para lo cual sólo necesitan ir aquí y logearse utilizando Live ID.

Luego, vamos a crear una aplicación Silverlight desde Visual Studio.

Ahora vamos a poner dentro del XAML los controles necesarios. Ya vamos a indicar en el ListBox el DataTemplate con el nombre de las Propiedades de nuestra clase.

<Grid x:Name="LayoutRoot" Background="White">
    
    <Grid.RowDefinitions>
        <RowDefinition Height="25" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    
    <StackPanel Orientation="Horizontal">
        <TextBox x:Name="txtBuscar" Width="200" />
        <Button x:Name="btnBuscar" 
                Content="Search" 
                Click="btnBuscar_Click" />
    </StackPanel>
    
    <ListBox x:Name="lstResultados" Grid.Row="1" 
             Height="257" Width="388" 
             RenderTransformOrigin="0.5,0.5">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Vertical" 
                            Margin="5,5,5,5">
                    <TextBlock Text="{Binding Path=Titulo}"/>
                    <HyperlinkButton NavigateUri="{Binding Path=Url}" 
                                     TargetName="_blank" 
                                     Content="{Binding Path=Url}" />
                    <TextBlock Text="{Binding Path=Descripcion}" 
                               TextWrapping="Wrap" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    
</Grid>

En el code-behind vamos a definir las funciones y clases necesarias para obtener y mostrar la información.

Primero vamos a definir la clase que utilizamos para enlazar los datos al ListBox

public class ResultadosBusqueda
{
    public string Url { get; set; }
    public string Titulo { get; set; }
    public string Descripcion { get; set; }
}

Agregamos las referencias a XML y LINQ ya que vamos a utilizarlas.

using System.Xml;
using System.Xml.Linq;

Definimos algunas constantes que nos van a servir para ir a buscar la información a la API.

// Acá va el API ID que has generado
const string appID = "API ID";
// Regionalizar la búsqueda 
const string marketBuscar = "es-ar";
// Tipo de búsqueda
const string sourcesBuscar = "web";
// NameSpace (usado para LINQ)
const string webNameSpace = "http://schemas.microsoft.com/LiveSearch/2008/04/XML/web";

 

Ahora definimos las funciones que llama a la API y que muestra la información

private void btnBuscar_Click(object sender, RoutedEventArgs e)
{
    WebClient wcBuscar = new WebClient();
    wcBuscar.OpenReadCompleted += 
        new OpenReadCompletedEventHandler(wcBuscar_OpenReadCompleted);
    wcBuscar.OpenReadAsync(new Uri("http://api.search.live.net/xml.aspx?AppID=" + 
                                    appID + "&Market=" + marketBuscar + 
                                    "&sources=" + sourcesBuscar + 
                                    "&query=" + 
                                    Uri.EscapeDataString(txtBuscar.Text)));
}
 
private void wcBuscar_OpenReadCompleted(Object sender, 
                                        OpenReadCompletedEventArgs e)
{
    Stream streamResult = e.Result;
 
    XDocument data = XDocument.Load(XmlReader.Create(streamResult));
 
    IEnumerable<XNode> nodes = 
        data.Descendants(XName.Get("Results", webNameSpace)).Nodes();
    if (nodes.Count() > 0)
    {
        var resultados = from uris in nodes
        select new ResultadosBusqueda
        {
        Titulo = 
            ((XElement)uris).Element(XName.Get("Title", webNameSpace)).Value,
        Descripcion = 
            ((XElement)uris).Element(XName.Get("Url", webNameSpace)).Value,
        Url = 
            ((XElement)uris).Element(XName.Get("Description", webNameSpace)).Value,
        };
 
        lstResultados.ItemsSource = resultados;            
    }                        
}

De esta manera tenemos nuestra aplicación conectada con Live Search.

Dibujo

Si uno no es un diseñador, hay veces que se puede complicar darle un buen look a nuestra aplicación. Para resolver este problema y poder darle un toque más interesante, podemos utilizar los temas que viene en Silverlight Toolkit.

El primer paso es instalar Silverlight Toolkit, para lo cual hay que ir aquí.

Asegúrense de descargar la Toolkit que corresponde a la versión de Silverlight que tengan instalada en su máquina.

Luego, creamos nuestra aplicación Silverlight desde Visual Studio y arrastramos de la barra de controles el tema al editor XAML, donde Visual Studio nos pone ya las referencias a la librería y nos crea el objeto para empezar a utilizarlo.

1

De esta manera vamos a ver como Visual Studio nos creó dos referencias, una al tema en sí y otra a System.Windows.Controls.Theming.Toolkit.

3

Además nos agrega en el XAML las referencias a la librería.

2

Agregaremos un contenedor dentro del tema, donde pondremos todos los controles necesarios.

<expressionLight:ExpressionLightTheme>
    <Border BorderThickness="3">
        <StackPanel>
            <TextBlock Text="PRUEBA DE TEXTO"/>
            <CheckBox Content="CheckBox" Margin="5" 
                      IsChecked="true" />
            <Button HorizontalAlignment="Left" Content="Boton" 
                    Width="150" Margin="5"/>
            <RadioButton Content="Opcion1" Margin="5" />
            <RadioButton Content="Opcion2" Margin="5" />
            <RadioButton Content="Opcion3" Margin="5" />
            <TextBox Text="VALOR" Margin="5"  />
        </StackPanel>
    </Border>
</expressionLight:ExpressionLightTheme>
<rainierOrange:RainierOrangeTheme>
    <Border BorderThickness="3">
        <StackPanel>
            <TextBlock Text="PRUEBA DE TEXTO" />
            <CheckBox Content="CheckBox" Margin="5" 
                      IsChecked="true" />
            <Button HorizontalAlignment="Left" Content="Boton" 
                    Width="150" Margin="5"/>
            <RadioButton Content="Opcion1" Margin="5" />
            <RadioButton Content="Opcion2" Margin="5" />
            <RadioButton Content="Opcion3" Margin="5" />
            <TextBox Text="VALOR" Margin="5"  />
        </StackPanel>
    </Border>
</rainierOrange:RainierOrangeTheme>

4

Ahora si nosotros vemos que hay alguna propiedad que nos gustaría cambiar solamente debemos definirla en el control. En el siguiente ejemplo modificamos el color del Texto de blanco a rojo.

<expressionLight:ExpressionLightTheme>
    <Border BorderThickness="3">
        <StackPanel>
            <TextBlock Text="PRUEBA DE TEXTO" Foreground="Red" />
            <CheckBox Content="CheckBox" Margin="5" 
                      IsChecked="true" />
            <Button HorizontalAlignment="Left" Content="Boton" 
                    Width="150" Margin="5"/>
            <RadioButton Content="Opcion1" Margin="5" />
            <RadioButton Content="Opcion2" Margin="5" />
            <RadioButton Content="Opcion3" Margin="5" />
            <TextBox Text="VALOR" Margin="5"  />
        </StackPanel>
    </Border>
</expressionLight:ExpressionLightTheme>
<rainierOrange:RainierOrangeTheme>
    <Border BorderThickness="3">
        <StackPanel>
            <TextBlock Text="PRUEBA DE TEXTO" />
            <CheckBox Content="CheckBox" Margin="5" 
                      IsChecked="true" />
            <Button HorizontalAlignment="Left" Content="Boton" 
                    Width="150" Margin="5"/>
            <RadioButton Content="Opcion1" Margin="5" />
            <RadioButton Content="Opcion2" Margin="5" />
            <RadioButton Content="Opcion3" Margin="5" />
            <TextBox Text="VALOR" Margin="5"  />
        </StackPanel>
    </Border>
</rainierOrange:RainierOrangeTheme>
5

También se puede customizar un tema por completo utilizando Visual Studio o Expression Blend.

Ya estuve hablando varias veces de juegos desarrollados en Silverlight y la posibilidad que nos da la herramienta de generar aplicaciones muy interesantes.

Ha sido lanzado SilverArcade.com, una comunidad de juegos desarrollados en Silverlight.

arcade1

Si tienen algún juego y quieren subirlo o solamente darse una vuelta para mirar y divertirse un rato, pueden ir aquí.

arcade2

More Posts Next page »