17 - Control ListView mostrando imágenes


Como hemos dicho un ListView nos permite mostrar una lista de elementos generalmente compuestos por varios controles visuales.

Veremos como podemos mostrar en cada item del ListView una imágen.

Problema

Implementar una aplicación que muestre en un ListView los nombres de países sudamericanos, la cantidad de habitantes que tiene cada uno y su bandera.

Como primer paso creamos un nuevo proyecto llamado "Proyecto22" seleccionando desde el menú de opciones del Visual Studio: Archivo -> Nuevo -> Proyecto.

La interfaz visual final que debe aparecer debe ser similar a esta:

ListView aplicacion universal para windows con imagenes

Copiamos en la carpeta Assets las imágenes de las banderas de los países sudamericanos:

ListView aplicacion universal para windows con imagenes

Crearemos una clase Pais que tenga tres propiedades (Nombre, CantidadHabitantes y Archivo).

Para crear una nueva clase con el Visual Studio vamos al menú de opciones: Proyecto -> Agregar nuevo elemento...

En este diálogo seleccionamos "Clase" e indicamos el nombre del archivo a crear "Pais.cs", similar a lo que hicimos en el concepto anterior.

Ahora en este archivo procedemos a implementar la clase Pais:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Proyecto22
{
    class Pais
    {
        public string Nombre { get; set; }
        public int CantidadHabitantes { get; set; }
        public string Archivo { get; set; }
    }
}

En el archivo MainPage.xaml.cs tenemos que crear una colección de datos de la clase Pais y enlazarla con el ListView que crearemos en la interfaz visual:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using System.Collections.ObjectModel;

// La plantilla de elemento Página en blanco está documentada en https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0xc0a

namespace Proyecto22
{
    /// <summary>
    /// Página vacía que se puede usar de forma independiente o a la que se puede navegar dentro de un objeto Frame.
    /// </summary>

    public sealed partial class MainPage : Page
    {

        private ObservableCollection<Pais> paises = new ObservableCollection<Pais>();

        public MainPage()
        {
            this.InitializeComponent();
            cargarListView();
        }

        private void cargarListView()
        {
            paises.Add(new Pais { Nombre = "Argentina", CantidadHabitantes = 40000000, Archivo = "Assets/argentina.png" });
            paises.Add(new Pais { Nombre = "Chile", CantidadHabitantes = 17000000, Archivo = "Assets/chile.png" });
            paises.Add(new Pais { Nombre = "Bolivia", CantidadHabitantes = 10000000, Archivo = "Assets/bolivia.png" });
            paises.Add(new Pais { Nombre = "Perú", CantidadHabitantes = 30000000, Archivo = "Assets/peru.png" });
            paises.Add(new Pais { Nombre = "Ecuador", CantidadHabitantes = 16000000, Archivo = "Assets/ecuador.png" });
            paises.Add(new Pais { Nombre = "Paraguay", CantidadHabitantes = 7000000, Archivo = "Assets/paraguay.png" });
            paises.Add(new Pais { Nombre = "Uruguay", CantidadHabitantes = 3000000, Archivo = "Assets/uruguay.png" });
            paises.Add(new Pais { Nombre = "Brasil", CantidadHabitantes = 200000000, Archivo = "Assets/brasil.png" });
            paises.Add(new Pais { Nombre = "Venezuela", CantidadHabitantes = 30000000, Archivo = "Assets/venezuela.png" });
            paises.Add(new Pais { Nombre = "Colombia", CantidadHabitantes = 48000000, Archivo = "Assets/colombia.png" });
            paises.Add(new Pais { Nombre = "Surinam", CantidadHabitantes = 500000, Archivo = "Assets/surinam.png" });
            paises.Add(new Pais { Nombre = "Guyana", CantidadHabitantes = 800000, Archivo = "Assets/guyana.png" });
            paises.Add(new Pais { Nombre = "Guyana Francesa", CantidadHabitantes = 250000, Archivo = "Assets/guyanafrancesa.png" });
            listView1.ItemsSource = paises;
        }
    }
}

Lo que cambia con el concepto anterior es que debemos iniciar la propiedad "Archivo" de cada objeto de la clase Pais con el nombre del archivo que almacenamos en la carpeta Assets (también guardamos el path donde se encuentra el archivo):

            paises.Add(new Pais { Nombre = "Guyana Francesa", CantidadHabitantes = 250000, Archivo = "Assets/guyanafrancesa.png" });

En el archivo MainPage.xaml tenemos:

<Page
    x:Class="Proyecto22.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Proyecto22"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <ListView x:Name="listView1" IsItemClickEnabled="True">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="{Binding Archivo}" Width="100" />
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="{Binding Nombre}" FontSize="30" Margin="10,10,10,10" />
                            <TextBlock Text="{Binding CantidadHabitantes}" FontSize="20"  Margin="10,0,10,10" />
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Page>

Cada item de la lista lo definimos dentro de la etiqueta "DataTemplate" del ListView:

            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="{Binding Archivo}" Width="100" />
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="{Binding Nombre}" FontSize="30" Margin="10,10,10,10" />
                            <TextBlock Text="{Binding CantidadHabitantes}" FontSize="20"  Margin="10,0,10,10" />
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>

Mediante el Binding (atadura o enlace) indicamos en la propiedad Source de la clase Image el nombre de archivo a recuperar y mostrar.:

                        <Image Source="{Binding Archivo}" Width="100" />

Este proyecto lo puede descargar en un zip desde este enlace :Proyecto22.zip

Problema propuesto

  1. Confeccionar un juego que muestre el nombre de un país a buscar y en la parte inferior un ListView con todas las banderas.
    Cuando se lo selecciona de la lista incrementar un contador si la respuesta es correcta o incorrecta. Inmediatamente mostrar otro país a buscar.

    La interfaz visual debe ser similar a esta:
    ListView
Solución

Este proyecto lo puede descargar en un zip desde este enlace :Proyecto23.zip

Retornar