Framework de Navegacion en Silverlight 3.- Parte 3

Continuando con el Framework de Navegación en Silverlight 3, aqui la tercera entrega del tema. En esta ocasión veremos como cargar datos dinamicos (desde una clase de modelado de datos), y como leer datos desde el url string.

Vínculos a los post anteriores relacionada con el tema:

Si no has leido, o quieres recordar lo que hemos visto hasta ahora, aquí los vinculos a los post anteriores:

Framework de Navegacion en Silverlight 3.- Parte 1
Framework de Navegacion en Silverlight 3.- Parte 2

Clases de modelado de datos

Para esta parte, incluiremos una clase para hacer un modelado de datos (aunque estos datos pueden venir desde cualquier fuente de datos).

FrameworkDeNavegacion301

Lo que nuestro código hace es crear un par de clases dentro de nuestro archivo Album.cs. La primera de ella en donde crearemos un Disco Músical (Album); con sus propiedades ID, Nombre del Album y el Artista. La segunda será una colección de Discos (Albums) que nos permitirá regresar un arreglo de 3 discos; así como los detalles de uno de ellos a partir de su ID.

using System.Collections.Generic;
using System.Linq;

namespace LLS.NavigationFramework.Part3.DataModel
{
    public class Album
    {
        public int ID { get; set; }
        public string AlbumName { get; set; }
        public string AlbumArtist { get; set; }
    }

    public class Albums
    {
        public List<Album> getAlbums()
        {
            List<Album> albums = new List<Album>();
            albums.Add(new Album() { ID = 1, AlbumName = "Dónde estan los Ladrones", AlbumArtist = "Shakira" });
            albums.Add(new Album() { ID = 2, AlbumName = "Galeria Caribe", AlbumArtist = "Ricardo Arjona" });
            albums.Add(new Album() { ID = 3, AlbumName = "Tierna la Noche", AlbumArtist = "Fey" });
            return albums;
        }
        public Album getAlbumById(int id)
        {
            var album = from a in getAlbums()
                        where a.ID == id
                        select a;
            return album.First();
        }
    }
}

Preparando la solución para accesar las nuevas páginas de navegación

Ademas necesitaremos agregar al menú de la aplicación el acceso a la nueva página de discos:

<StackPanel Margin="10" VerticalAlignment="Top" Grid.Column="0">
    <HyperlinkButton Content="Inicio" FontSize="14" Click="HyperlinkButton_Click" Tag="Inicio" />
    <HyperlinkButton Content="Acerca" FontSize="14" Click="HyperlinkButton_Click" Tag="Acerca" />
    <HyperlinkButton Content="Discos" FontSize="14" Click="HyperlinkButton_Click" Tag="Discos" />
</StackPanel>
<nav:Frame x:Name="MainFrame" Grid.Column="1" UriMapper="{staticResource uriMapper}" Source="Inicio" />

Y agregaremos al mapeador de uris (UriMapper) el acceso a la nueva página (Page) de discos, así como un mapeo de uri (UriMapping) en donde configuraremos el uso de parametros dinámicos:

<navcore:UriMapper x:Key="uriMapper">
    <navcore:UriMapping Uri="Inicio" MappedUri="/Content/Home.xaml" />
    <navcore:UriMapping Uri="Acerca" MappedUri="/Content/About.xaml" />
    <navcore:UriMapping Uri="Discos" MappedUri="/Content/Albums.xaml" />
    <navcore:UriMapping Uri="Disco/{id}" MappedUri="/Content/Album.xaml?id={id}" />
</navcore:UriMapper>

Mostrando la lista de discos desde nuestra fuente de datos

Para mostrar la lista de discos en nuestra fuente de datos, agregamos una página (page) (página de silvelirght {silverlight page} del framework de navegación que veiamos en la parte 2 de la serie de post sobre este tema) que llamaremos Albums.xaml.

En nuestra página (page) tendremos un Control de Elementos (ItemsControl), en donde le definiremos su Plantilla (ItemTemplate), que a su vez será una plantilla de datos (DataTemplate) de una lista de botones (HyperlinkButton) en donde el texto será el nombre del disco y tu tag será el ID del disco.

<StackPanel x:Name="LayoutRoot">
    <TextBlock FontSize="24" Foreground="Chocolate" Text="Colección de Discos" />
    <ItemsControl x:Name="AlbumList">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <HyperlinkButton Content="{Binding AlbumName}" Tag="{Binding ID}" Click="HyperlinkButton_Click" />
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</StackPanel>

Y en el código detras de este xaml, primero cargaremos los datos de la colección de discos en el loader de la clase; y en el evento del click de los botones lo que haremos es obtener el tag del boton para crear un url que apunte a la página (page) de detalles del disco usando el id del disco

Aqui es donde tenemos la parte medular de este post en donde haremos uso del Servicio de Navegación (NavigationService) que ofrece el Framework, el cual nos permite Navegar (Navigate) hacia una nueva página en nuestro Frame (Frame) donde tenemos contenidas nuestras Páginas (Page)

public partial class Albums : Page
{
    public Albums()
    {
        InitializeComponent();
        Loaded += new RoutedEventHandler(Albums_Loaded);
    }

    void Albums_Loaded(object sender, RoutedEventArgs e)
    {
        LLS.NavigationFramework.Part3.DataModel.Albums a = new LLS.NavigationFramework.Part3.DataModel.Albums();
        this.AlbumList.ItemsSource = a.getAlbums();
    }

    private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
    {
        HyperlinkButton btn = sender as HyperlinkButton;
        string id = btn.Tag.ToString();
        this.NavigationService.Navigate(new Uri(string.Format("Disco/{0}", id), UriKind.Relative));
    }
}

Mostrando los detalles de un disco

Por último, agregaremos una página (page) que llamaremos Album, en donde mostraremos los detalles de un disco a partir de su identificador leido desde el url,

Aquí utilizaremos otro compomente importante en el framework de navegación, el Contexto de Navegación (NavigationContext), que nos permitirá leer desde la cadena de consulta (QueryString).

Recordemos que en nuestro Mapeos de Uri (UriMapper) hacemos llamadas del tipo /Content/Album.xaml?id={id} de donde podemos obtener el id del album a consultar.

Todo esto en el loader de la Página (Page).

Nuestro xaml:

<StackPanel x:Name="LayoutRoot">
    <TextBlock FontSize="24" Foreground="Chocolate" Text="Detalles del Disco" />
    <StackPanel Orientation="Vertical" x:Name="AlbumInfo">
        <TextBlock x:Name="AlbumName" Text="{Binding AlbumName}" />
        <TextBlock x:Name="AlbumArtist" Text="{Binding AlbumArtist}" />
    </StackPanel>
</StackPanel>

Y nuestro código:

public partial class Album : Page
{
    public Album()
    {
        InitializeComponent();
        Loaded += new RoutedEventHandler(Album_Loaded);
    }
    void Album_Loaded(object sender, RoutedEventArgs e)
    {
        LLS.NavigationFramework.Part3.DataModel.Albums albums = new LLS.NavigationFramework.Part3.DataModel.Albums();
        LLS.NavigationFramework.Part3.DataModel.Album album = null;
        if (this.NavigationContext.QueryString["id"] != null)
        {
            album = albums.getAlbumById(Convert.ToInt32(this.NavigationContext.QueryString["id"]));
        }
        this.DataContext = album;
    }
}

Tiempo de ejecución

En esta ocasión haremos notar los url del tipo:

Donde encontrar este código:

KodiakLS.codeplex.com (I’m in love with codeplex.com)

Proximamente:

Ya que hemos entendido los  conceptos básicos del Framework de Navegación de Silverlight 3 estamos listos para la última parte de nuestro tema:

  • Plantilla de proyecto para el framework de navegación.

Saludos