Solución Reto Windows Phone: Control Panorama

En el tercer reto de Windows Phone aprendimos cómo utilizar el control Panorama y personalizarlo a nuestro gusto. Cómo reto hay que implementar un control Panorama parecido al Hub de Imágenes como se muestra más abajo:

Para solucionar este reto necesitamos:

Visual Studio. Si ya tienes VS instalado perfecto, pero por si acaso, aquí tienes el enlace de descarga de la versión gratuita express o de la Ultimate Trial.

 

Windows Phone developer tools 7.1.Con esta descarga tendremos todo lo necesario para empezar a programar aplicaciones para los dispositivos con Windows Phone

En esta ocasión crearemos un proyecto nuevo del tipo aplicación panorama para después ir editándolo para crear el aspecto que queremos obtener.

Modificar el ItemViewModel

Para mostrar los datos en los ListBox de la vista del panorama vamos a agregar una propiedad al ItemViewModel. Esta propiedad será una lista de cadenas que harán referencia a las url de las imágenes que vamos a mostrar. Esa lista será los álbumes que vamos a mostrar en el PanoramaItem referente a Albums.

 

private List<string> _imageUrl;

public List<string> ImageUrl
{
    get
    {
        return _imageUrl;
    }
    set
    {
        if (value != _imageUrl)
        {
            imageUrl = value;
            NotifyPropertyChanged("ImageUrl");
        }
    }
}

 

Carga de datos

Como vamos a crear 3 PanoramaItems vamos a crear 3 ObservableCollection<ItemViewModel> para mostrar los datos en cada uno.

 

ObservableCollection<ItemViewModel> para mostrar los datos en cada uno.


public MainViewModel()
{
    this.Items = new ObservableCollection<ItemViewModel>();
    this.Items2 = new ObservableCollection<ItemViewModel>();
    this.Items3 = new ObservableCollection<ItemViewModel>();
}

public ObservableCollection<ItemViewModel> Items { get; private set; }
public ObservableCollection<ItemViewModel> Items2 { get; private set; }
public ObservableCollection<ItemViewModel> Items3 { get; private set; }

 

Después en el método LoadData insertaremos los elementos en las colecciones dependiendo de lo datos que vayamos a mostrar.En la primera colección tenemos que mostrar la lista albums, todos, favoritos.

 

this.Items.Add(new ItemViewModel() { LineOne = "albums" });
this.Items.Add(new ItemViewModel() { LineOne = "todo" });
this.Items.Add(new ItemViewModel() { LineOne = "favoritos"});

 

En la segunda tenemos que mostrar una serie de imágenes así que iremos insertando las urls de las imágenes que se verán.

 

this.Items2.Add(new ItemViewModel() {LineOne="Imágenes de muestra",
ImageUrl =new List<string>(){
    @"https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-40-66-metablogapi/8420.clip_5F00_image004_5F00_538437AC.jpg",
    @"https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-40-66-metablogapi/8420.clip_5F00_image004_5F00_538437AC.jpg" ,
    @"http://i1.social.microsoft.com/profile/u/avatar.jpg?displayname=esmsdn&size=large",
    @"https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-40-66-metablogapi/2068.clip_5F00_image001_5F00_647C53C1.png" ,
    @"http://t1.gstatic.com/images?q=tbn:ANd9GcTGGN9puLMHy2guidWCsotOSen_eadW5y5-bXbfXSFUh9UBxh9eIA" ,
    @"http://i.msdn.microsoft.com/dynimg/IC425815.png"
}
});

 

Utilizaremos LineOne como título del PanoramaItem y la lista de urls para mostrar las imágenes.

Por último cargaremos los datos de los álbumes. Tendremos 3 elementos ItemViewModel, uno por cada álbum.

 

this.Items3.Add(new ItemViewModel() { LineOne = "Retos", LineTwo = "Herramientas",
    ImageUrl = new List<string>() { 
    "https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-40-66-metablogapi/8420.clip_5F00_image004_5F00_538437AC.jpg",
    "https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-40-66-metablogapi/2068.clip_5F00_image001_5F00_647C53C1.png",
    "http://t1.gstatic.com/images?q=tbn:ANd9GcTGGN9puLMHy2guidWCsotOSen_eadW5y5-bXbfXSFUh9UBxh9eIA"}
});

this.Items3.Add(new ItemViewModel() { LineOne = "WP7",LineTwo="Imágenes de wp7" ,
    ImageUrl = new List<string>() {
    "https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-40-66-metablogapi/1374.image_5F00_thumb_5F00_1498F9DA.png",
    "http://i.msdn.microsoft.com/dynimg/IC425815.png"
} });

this.Items3.Add(new ItemViewModel() { LineOne = "Microsoft", LineTwo ="Logos",
    ImageUrl = new List<string>() {
    "http://i1.social.microsoft.com/profile/u/avatar.jpg?displayname=esmsdn&size=large"
} });

 

Crear los PanoramaItems

Ya tenemos cargados todos los datos que queremos utilizar. Ahora iremos a la vista de diseño, crearemos los nuevos PanoramaItems, los personalizaremos y enlazaremos los datos para mostrarlos.

En el primer PanoramaItem enlazaremos la propiedad Items y mostraremos en el TextBlock la propiedad LineOne.

 

<controls:PanoramaItem Header="galeria" Foreground="Black">
<!--Double line list with text wrapping-->
    <ListBox Margin="0,0,-12,0" ItemsSource="{Binding Items}">
        <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Margin="0,0,0,17" Width="432" Height="78">
                <TextBlock Text="{Binding LineOne}" TextWrapping="Wrap"
                Style="{StaticResource PhoneTextExtraLargeStyle}" Foreground="Black" />
            </StackPanel>
        </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</controls:PanoramaItem>

 

En el segundo PanoramaItem vamos a crear un grid para mostrar las imágenes de un álbum que corresponde con la propiedad Items2. Como título del PanoramaItem cogeremos la propiedad LineOne que corresponderá con el título del álbum y después en cada posición del grid cargaremos una imagen. Haremos el PanoramaItem en horizontal.

 

<controls:PanoramaItem Header="{Binding Items2[0].LineOne}" Orientation="Horizontal" Foreground="Black">
    <!--Double line list with image placeholder and text wrapping-->
    <Grid >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="160"/>
        <ColumnDefinition Width="160"/>
        <ColumnDefinition Width="160"/>
        <ColumnDefinition Width="160"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="160" />
        <RowDefinition Height="160"/>
        <RowDefinition Height="160"/>
    </Grid.RowDefinitions>
    <Image Source="{Binding Items2[0].ImageUrl[0]}" Grid.Column="0" Grid.Row="0"
    Height="100" Width="100" />
    <Image Source="{Binding Items2[0].ImageUrl[1]}" Grid.Column="1" Grid.Row="0"
    Height="150" Width="150" />
    <Image Source="{Binding Items2[0].ImageUrl[2]}" Grid.Column="2" Grid.Row="0"
    Height="150" Width="150"  />
    <Image Source="{Binding Items2[0].ImageUrl[3]}" Grid.Column="3" Grid.Row="0"
    Height="150" Width="150"  />
    <Image Source="{Binding Items2[0].ImageUrl[4]}" Grid.Column="0" Grid.Row="1"
    Height="150" Width="150"  />
    <Image Source="{Binding Items2[0].ImageUrl[5]}" Grid.Column="1" Grid.Row="1"
    Height="150" Width="150" />
    <Image Source="{Binding Items2[0].ImageUrl[6]}" Grid.Column="2" Grid.Row="1"
    Height="150" Width="150" />
    <Image Source="{Binding Items2[0].ImageUrl[7]}" Grid.Column="3" Grid.Row="1"
    Height="150" Width="150"  />
    </Grid>
</controls:PanoramaItem>

 

Por último crearemos el tercer PanoramaItem en el que mostraremos 3 álbumes. Estos álbumes tendrán un título y una breve descripción que serán las propiedades LineOne y Line Two y una lista de urls de imágenes que forman parte del álbum. Se mostrarán sólo las 3 primeras imágenes.

 

<controls:PanoramaItem Header="Albums" Foreground="Black">
    <ListBox Margin="0,0,-12,0" ItemsSource="{Binding Items3}" Foreground="Black">
    <ListBox.ItemTemplate>
        <DataTemplate>
        <StackPanel Orientation="Vertical" Margin="0,0,0,17">
            <StackPanel Width="311">
            <TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" 
            Style="{StaticResource PhoneTextExtraLargeStyle}" Foreground="Black"/>
            <TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12,-6,12,0"
            Style="{StaticResource PhoneTextSubtleStyle}" Foreground="#99000000"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
            <Image Source="{Binding ImageUrl[0]}" Margin="12,0,9,0"
            Height="100" Width="100"/>
            <Image Source="{Binding ImageUrl[1]}" Margin="12,0,9,0"
            Height="100" Width="100"/>
            <Image Source="{Binding ImageUrl[2]}" Margin="12,0,9,0"
            Height="100" Width="100"/>
            </StackPanel>
        </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
    </ListBox>
</controls:PanoramaItem>

 

Para mejorar un poco el aspecto vamos a cambiar el fondo del control Panorama poniendo el mismo fondo que tiene el blog de MSDN, por ello hemos puesto la propiedad Foreground de todos los PanoramaItems a Black para que se puedan distinguir bien las letras.

 

<controls:Panorama Title="Imágenes" Foreground="Black">
    <controls:Panorama.Background>
        <ImageBrush ImageSource=
    "https://blogs.msdn.com/Themes/Blogs/MicrosoftBlue/images/header_bkg_wol.jpg"/>
    </controls:Panorama.Background>

 

Con todo esto hemos creado un control Panorama parecido al Hub de imágenes.