Compartir a través de


Vista de lista y vista de cuadrícula

La mayoría de las aplicaciones manipulan y muestran conjuntos de datos, como una galería de imágenes o un conjunto de mensajes de correo electrónico. El marco de interfaz de usuario XAML proporciona controles ListView y GridView que facilitan la visualización y manipulación de datos en la aplicación.

Nota:

ListView y GridView derivan de la clase ListViewBase , por lo que tienen la misma funcionalidad, pero muestran datos de forma diferente. En este artículo, las discusiones sobre la vista de lista se aplican a los controles ListView y GridView, a menos que se especifique lo contrario. Podemos hacer mención a clases como ListView o ListViewItem, pero el prefijo List se puede reemplazar por Grid para el equivalente de cuadrícula correspondiente (GridView o GridViewItem).

Los controles ListView y GridView proporcionan muchas ventajas a medida que trabaja con colecciones. Ambos son fáciles de implementar y proporcionar la interfaz de usuario básica, la interacción y el desplazamiento mientras se pueden personalizar fácilmente. Y ambos se pueden enlazar a orígenes de datos dinámicos existentes o a datos codificados de forma rígida que se proporcionan en el propio CÓDIGO XAML o el código subyacente.

Ambos controles son flexibles para su uso en una variedad de escenarios, pero, en general, funcionan mejor con colecciones en las que todos los elementos tienen la misma estructura básica y apariencia, así como el mismo comportamiento de interacción. Es decir, todos deben realizar la misma acción cuando se hace clic en ellos (por ejemplo, para abrir un vínculo o examinar).

Comparar ListView y GridView

ListView

El control ListView muestra los datos apilados verticalmente en una sola columna. ListView funciona mejor para los elementos que tienen texto como punto focal y para las colecciones que están diseñadas para leerse de arriba abajo (por ejemplo, ordenados alfabéticamente). Algunos casos de uso habituales de ListView son las listas de mensajes y los resultados de la búsqueda. Si necesita mostrar colecciones en varias columnas o en un formato similar a una tabla, no debe usar ListView. En su lugar, considere la posibilidad de usar un control DataGrid .

Captura de pantalla de una vista de lista de datos agrupados alfabéticamente.

GridView

El control GridView presenta una colección de elementos en filas y columnas que se pueden desplazar verticalmente. Los datos se apilan horizontalmente hasta que rellenan una columna y, a continuación, continúan con la siguiente fila de la columna. GridView funciona mejor para las colecciones que tienen imágenes como punto focal o cuyos elementos se pueden leer de lado a lado o no se ordenan en un orden específico. Un caso de uso habitual de GridView es una galería de productos o de fotos.

Captura de pantalla de una biblioteca de contenido de fotos mostradas como una vista de cuadrícula.

¿Qué control de colección debes usar? Comparación con ItemsRepeater

Es importante comprender las diferencias entre estos tipos de controles antes de decidir cuál usar.

ListView y GridView

Los controles ListView y GridView enriquecidos con características funcionan de forma predeterminada. No requieren personalización, pero se pueden personalizar fácilmente. Cada uno tiene su propia interfaz de usuario y experiencia de usuario integrada y está diseñada para mostrar casi cualquier tipo de colección tal como está.

ItemsRepeater

El control ItemsRepeater también se usa para mostrar colecciones, pero está diseñado como un bloque de creación para crear un control personalizado que se adapte a sus requisitos de interfaz de usuario concretos. No tiene las mismas características y funcionalidades integradas que ListView y GridView, por lo que deberá implementar las características o interacciones necesarias. Use ItemsRepeater si tiene una interfaz de usuario altamente personalizada que no se puede crear mediante ListView o GridView, o si el origen de datos requiere un comportamiento diferente para cada elemento.

Para más información sobre ItemsRepeater, lea su documentación sobre directrices y API.

UWP y WinUI 2

Importante

La información y los ejemplos de este artículo están optimizados para aplicaciones que usan el SDK de Aplicaciones para Windows y WinUI 3, pero generalmente son aplicables a las aplicaciones para UWP que usan WinUI 2. Consulte el material de referencia de las API de UWP para obtener información y ejemplos específicos de la plataforma.

Esta sección contiene información que necesita para usar el control en una aplicación para UWP o WinUI 2.

Existen API para estos controles en el espacio de nombres Windows.UI.Xaml.Controls .

  • API de UWP: clase ListView, clase GridView, propiedad ItemsSource, propiedad Items
  • Abra la aplicación Galería de WinUI 2 y vea ListView o GridView en acción. La aplicación WinUI 2 Gallery incluye ejemplos interactivos de la mayoría de los controles, características y funcionalidades de WinUI 2. Obtenga la aplicación en Microsoft Store u obtenga el código fuente en GitHub.

Se recomienda usar la versión más reciente de WinUI 2 para obtener los estilos, las plantillas y las características más actuales de todos los controles.

Crear una vista de lista o una vista de cuadrícula

Abra la aplicación Galería de WinUI 3 y vea listView o GridView en acción.

La aplicación WinUI 3 Gallery incluye ejemplos interactivos de la mayoría de los controles, características y funcionalidades de WinUI 3. Obtenga la aplicación de Microsoft Store u obtenga el código fuente en GitHub.

ListView y GridView son de tipo ItemsControl, por lo que pueden contener una colección de elementos de cualquier tipo. Un control ListView o GridView debe tener elementos en su colección Items para poder mostrar cualquier elemento en la pantalla. Para rellenar la vista, puede agregar elementos directamente a la colección o establecer la propiedad ItemsSource en un origen de datos.

Precaución

Puede usar la propiedad Items o ItemsSource para rellenar la lista, pero no puede usar ambas al mismo tiempo. Si estableces la propiedad ItemsSource y agregas un elemento en XAML, se omite el elemento agregado. Si establece la propiedad ItemsSource y agrega un elemento a la colección Items en el código, se produce una excepción.

Muchos de los ejemplos de este artículo rellenan directamente la colección Items por motivos de simplicidad. Sin embargo, es más común que los elementos de una lista provengan de un origen dinámico, como una lista de libros de una base de datos en línea. Use la propiedad ItemsSource para este propósito.

Agregar elementos a un control ListView o GridView

Puedes agregar elementos a la colección ListView o GridView Items mediante XAML o código para producir el mismo resultado. Normalmente, agregarías elementos a través de XAML si tienes un pequeño número de elementos que no cambian y se definen fácilmente, o si generas los elementos en el código en tiempo de ejecución.

Método 1: Agregar elementos a la colección Items

  • Opción 1: Agregar elementos a través de XAML

    <!-- No corresponding C# code is needed for this example. -->
    
    <ListView x:Name="Fruits">
    <x:String>Apricot</x:String>
    <x:String>Banana</x:String>
    <x:String>Cherry</x:String>
    <x:String>Orange</x:String>
    <x:String>Strawberry</x:String>
    </ListView>
    
  • Opción 2: Agregar elementos a través del código

    <StackPanel Name="FruitsPanel"></StackPanel>
    
    // Create a new ListView and add content.
    ListView Fruits = new ListView();
    Fruits.Items.Add("Apricot");
    Fruits.Items.Add("Banana");
    Fruits.Items.Add("Cherry");
    Fruits.Items.Add("Orange");
    Fruits.Items.Add("Strawberry");
    
    // Add the ListView to a parent container in the visual tree (which you created in the corresponding XAML file).
    FruitsPanel.Children.Add(Fruits);
    

Ambas opciones generan la misma vista de lista, como se muestra aquí:

Captura de pantalla de una vista de lista sencilla que muestra una lista de frutas.

Método 2: Agregar elementos estableciendo la propiedad ItemsSource

Normalmente, usaría un control ListView o GridView para mostrar datos de un origen, como una base de datos o Internet. Para rellenar un control ListView o GridView desde un origen de datos, establezca su propiedad ItemsSource en una colección de elementos de datos. Este método funciona mejor si ListView o GridView van a contener objetos de clase personalizados, como se muestra en los ejemplos siguientes.

  • Opción 1: Establecer ItemsSource en el código

    Aquí, la propiedad ListView ItemsSource se establece en el código directamente en una instancia de una colección.

    <StackPanel x:Name="ContactPanel"></StackPanel>
    
    // Class definition should be provided within the namespace being used, outside of any other classes.
    
    this.InitializeComponent();
    
    // Instead of adding hard coded items to an ObservableCollection as shown here,
    //the data could be pulled asynchronously from a database or the internet.
    ObservableCollection<Contact> Contacts = new ObservableCollection<Contact>();
    
    // You create Contact objects by providing a first name, last name, and company for the Contact constructor.
    // They are then added to the ObservableCollection Contacts.
    Contacts.Add(new Contact("John", "Doe", "Contoso, LTD."));
    Contacts.Add(new Contact("Jane", "Doe", "Fabrikam, Inc."));
    Contacts.Add(new Contact("Santa", "Claus", "Alpine Ski House"));
    
    // Create a new ListView (or GridView) for the UI, and add content by setting ItemsSource
    ListView ContactsLV = new ListView();
    ContactsLV.ItemsSource = Contacts;
    
    // Add the ListView to a parent container in the visual tree (which you created in the corresponding XAML file)
    ContactPanel.Children.Add(ContactsLV);
    
  • Opción 2: Establecer ItemsSource en XAML

    También puedes enlazar la propiedad ItemsSource a una colección en XAML. Aquí, ItemsSource está enlazado a una propiedad pública denominada Contacts, que expone la colección de datos privada de la página, denominada _contacts.

    <ListView x:Name="ContactsLV" ItemsSource="{x:Bind Contacts}"/>
    
    // Provide a class definition within the namespace being used, outside of any other classes.
    // These two declarations belong outside the main page class.
    private ObservableCollection<Contact> _contacts = new ObservableCollection<Contact>();
    
    public ObservableCollection<Contact> Contacts
    {
        get { return this._contacts; }
    }
    
    // Define this method within your main page class.
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
    
        // Instead of hard coded items, the data could be pulled
        // asynchronously from a database or the internet.
        Contacts.Add(new Contact("John", "Doe", "Contoso, LTD."));
        Contacts.Add(new Contact("Jane", "Doe", "Fabrikam, Inc."));
        Contacts.Add(new Contact("Santa", "Claus", "Alpine Ski House"));
    }
    

Ambas opciones generarán la misma vista de lista, como se muestra en la captura de pantalla siguiente. (La vista de lista muestra la representación de cadena de cada elemento, porque no se define una plantilla de datos para este ejercicio).

Captura de pantalla que muestra una vista de lista sencilla con el conjunto de propiedades ItemsSource.

Importante

Sin una plantilla de datos definida, los objetos de clase personalizados aparecerán en la vista de lista con su valor de cadena solo si tienen un método ToString definido.

En la sección siguiente se detalla más detalladamente cómo representar visualmente elementos de clase simples y personalizados correctamente en una plantilla ListView o GridView.

Para obtener más información sobre el enlace de datos, consulta Introducción al enlace de datos.

Nota:

Si necesita mostrar datos agrupados en la vista de lista, debe enlazar a una clase CollectionViewSource . CollectionViewSource actúa como proxy para la clase de colección en XAML y permite la compatibilidad con la agrupación. Para obtener más información, consulta CollectionViewSource.

Personalización de la apariencia con una plantilla de datos

Mediante el uso de una plantilla de datos en un control ListView o GridView, puede definir cómo se van a visualizar los elementos y los datos. De manera predeterminada, un elemento de datos se muestra en la vista de lista como una representación de cadena del objeto de datos al que está enlazado. Puede mostrar la representación de cadena de una propiedad determinada del elemento de datos estableciendo DisplayMemberPath en esa propiedad.

Sin embargo, normalmente es posible que desee mostrar una presentación más completa de los datos. Para especificar cómo se van a mostrar los elementos de la vista de lista o la vista de cuadrícula, cree una clase DataTemplate . El XAML de DataTemplate define el diseño y la apariencia de los controles que se usan para mostrar un elemento individual. Los controles del diseño se pueden enlazar a las propiedades de un objeto de datos o pueden tener contenido estático definido en línea.

Importante

Al usar la extensión de marcado x:Bind en DataTemplate, debe especificar el tipo de datos (x:DataType) en la plantilla de datos.

Una plantilla de datos simple de ListView

En este ejemplo, el elemento de datos es una cadena simple. Para agregar una imagen a la izquierda de la cadena y mostrar la cadena en teal, defina DataTemplate en línea dentro de la definición listView. Este es el mismo control ListView que creó anteriormente mediante la opción 1 en el método 1.

<!--No corresponding code is needed for this example.-->
<ListView x:Name="FruitsList">
                <ListView.ItemTemplate>
                    <DataTemplate x:DataType="x:String">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="47"/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <Image Source="Assets/placeholder.png" Width="32" Height="32"
                                HorizontalAlignment="Left" VerticalAlignment="Center"/>
                            <TextBlock Text="{x:Bind}" Foreground="Teal" FontSize="14"
                                Grid.Column="1" VerticalAlignment="Center"/>
                        </Grid>
                    </DataTemplate>
                </ListView.ItemTemplate>
                <x:String>Apricot</x:String>
                <x:String>Banana</x:String>
                <x:String>Cherry</x:String>
                <x:String>Orange</x:String>
                <x:String>Strawberry</x:String>
            </ListView>

Este es el modo en que se muestran los elementos de datos al aplicar una plantilla de datos simple de ListView:

Captura de pantalla de la lista que se muestra después de aplicar una plantilla de datos listView simple.

Plantilla de datos ListView para objetos de clase personalizados

En el ejemplo siguiente, el elemento de datos es un objeto Contact. Para agregar la imagen de contacto a la izquierda del nombre de contacto y la empresa, defina DataTemplate en línea dentro de la definición listView. Esta plantilla de datos ListView se creó en la opción 2 en el método 2, como se mostró anteriormente.

<ListView x:Name="ContactsLV" ItemsSource="{x:Bind Contacts}">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="local:Contact">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Image Grid.Column="0" Grid.RowSpan="2" Source="Assets/grey-placeholder.png" Width="32"
                    Height="32" HorizontalAlignment="Center" VerticalAlignment="Center"></Image>
                <TextBlock Grid.Column="1" Text="{x:Bind Name}" Margin="12,6,0,0"
                    Style="{ThemeResource BaseTextBlockStyle}"/>
                <TextBlock  Grid.Column="1" Grid.Row="1" Text="{x:Bind Company}" Margin="12,0,0,6"
                    Style="{ThemeResource BodyTextBlockStyle}"/>
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Aquí se muestra cómo se muestran los elementos de datos al aplicar una plantilla de datos ListView para objetos de clase personalizados:

Captura de pantalla de una lista que se muestra después de aplicar una plantilla de datos ListView para objetos de clase personalizados.

Las plantillas de datos son la forma principal de definir la apariencia del control ListView. También pueden afectar significativamente al rendimiento si la lista contiene un gran número de elementos.

Puede definir la plantilla de datos insertada dentro de la definición ListView o GridView, como se muestra en el código anterior o por separado en una sección Recursos. Si la define fuera de la definición de ListView o GridView, debe asignarle un atributo x:Key a la plantilla de datos y asignarla a la propiedad ItemTemplate de ListView o GridView mediante esa clave.

Para obtener más información y ejemplos de cómo usar las plantillas de datos y los contenedores de elementos para definir la apariencia de los elementos de la lista o cuadrícula, consulta Plantillas y contenedores de elementos.

Cambiar el diseño de elementos

Cuando agrega elementos a un control ListView o GridView, ajusta automáticamente cada elemento de un contenedor de elementos y, a continuación, establece todos los contenedores de elementos. La forma en que se diseñan estos contenedores de elementos depende de la propiedad ItemsPanel del control.

  • ListView, de forma predeterminada, usa ItemsStackPanel, que genera una lista vertical:

    Captura de pantalla de una vista de lista sencilla que muestra una lista vertical de elementos.

  • GridView usa ItemsWrapGrid, que agrega elementos horizontalmente y ajusta y se desplaza verticalmente:

    Captura de pantalla de una vista de cuadrícula sencilla que muestra una lista horizontal de elementos.

Puede modificar el diseño de los elementos ajustando las propiedades en el panel de elementos o puede reemplazar el panel predeterminado por otro panel.

Nota:

Si cambia ItemsPanel, no deshabilite la virtualización. ItemsStackPanel y ItemsWrapGrid admiten la virtualización, por lo que estas clases son seguras para su uso. Si usa cualquier otro panel, puede deshabilitar la virtualización y ralentizar el rendimiento de la vista de lista. Para obtener más información, consulta los artículos de vista de lista en Rendimiento.

En este ejemplo se muestra cómo hacer que un control ListView establezca sus contenedores de elementos en una lista horizontal cambiando la propiedad Orientation de ItemsStackPanel.

Dado que la vista de lista se desplaza verticalmente, de forma predeterminada, también debe ajustar algunas propiedades en el ScrollViewer interno de la vista de lista para que se desplace horizontalmente.

Importante

Los ejemplos siguientes se muestran con el ancho de la vista de lista sin restricciones, por lo que no se muestran las barras de desplazamiento horizontales. Si ejecuta este código, puede establecer Width="180" que ListView muestre las barras de desplazamiento.

<ListView Height="60"
          ScrollViewer.HorizontalScrollMode="Enabled"
          ScrollViewer.HorizontalScrollBarVisibility="Auto"
          ScrollViewer.VerticalScrollMode="Disabled"
          ScrollViewer.VerticalScrollBarVisibility="Hidden">
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <ItemsStackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
    <x:String>Apricot</x:String>
    <x:String>Banana</x:String>
    <x:String>Cherry</x:String>
    <x:String>Orange</x:String>
    <x:String>Strawberry</x:String>
</ListView>

Este es el modo en que se muestra la lista:

Captura de pantalla de una vista de lista horizontal.

En el ejemplo siguiente, ListView establece elementos en una lista de ajuste vertical mediante ItemsWrapGrid en lugar de ItemsStackPanel.

Importante

Debe restringir el alto de la vista de lista para forzar el control a encapsular los contenedores.

<ListView Height="100"
          ScrollViewer.HorizontalScrollMode="Enabled"
          ScrollViewer.HorizontalScrollBarVisibility="Auto"
          ScrollViewer.VerticalScrollMode="Disabled"
          ScrollViewer.VerticalScrollBarVisibility="Hidden">
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <ItemsWrapGrid/>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
    <x:String>Apricot</x:String>
    <x:String>Banana</x:String>
    <x:String>Cherry</x:String>
    <x:String>Orange</x:String>
    <x:String>Strawberry</x:String>
</ListView>

Este es el modo en que se muestra la lista:

Captura de pantalla de una vista de lista con un diseño de cuadrícula.

Si muestra datos agrupados en la vista de lista, ItemsPanel determina cómo se diseñan los grupos de elementos, no cómo se diseñan los elementos individuales. Por ejemplo, si usas el elemento ItemsStackPanel horizontal mostrado anteriormente para mostrar datos agrupados, los grupos se organizan horizontalmente, pero los elementos de cada grupo siguen apilados verticalmente, como se muestra aquí:

Captura de pantalla de una vista de lista horizontal agrupada..

Selección e interacción de elementos

Puede elegir entre varias maneras de permitir que los usuarios interactúen con una vista de lista. De manera predeterminada, los usuarios pueden seleccionar un solo elemento. Puedes cambiar la propiedad SelectionMode para habilitar la selección múltiple o para deshabilitar la selección. Puede establecer la propiedad IsItemClickEnabled para que los usuarios hagan clic en un elemento (por ejemplo, un botón) para invocar una acción en lugar de seleccionar el elemento.

Nota:

Tanto ListView como GridView usan la enumeración ListViewSelectionMode para sus propiedades SelectionMode. IsItemClickEnabled se establece en False de forma predeterminada, por lo que solo tiene que establecerlo para habilitar el modo de clic.

En esta tabla se muestran las formas en que un usuario puede interactuar con una vista de lista y cómo puede responder a la interacción.

Para habilitar esta interacción: Use estos valores de configuración: Controle este evento: Use esta propiedad para obtener el elemento seleccionado:
Sin interacción SelectionMode="None"
IsItemClickEnabled="False"
N/D N/D
Selección única SelectionMode="Single"
IsItemClickEnabled="False"
SelectionChanged SelectedItem
SelectedIndex
Selección múltiple SelectionMode="Multiple"
IsItemClickEnabled="False"
SelectionChanged SelectedItems
Selección extendida SelectionMode="Extended"
IsItemClickEnabled="False"
SelectionChanged SelectedItems
Haga clic SelectionMode="None"
IsItemClickEnabled="True"
ItemClick N/D

Nota:

Puedes habilitar IsItemClickEnabled para generar un evento ItemClick mientras SelectionMode también está establecido en Single, Multiple o Extended. Si lo hace, el evento ItemClick se genera primero y, a continuación, se genera el evento SelectionChanged. En algunos casos (por ejemplo, si va a otra página en el controlador de eventos ItemClick), el evento SelectionChanged no se genera y el elemento no está seleccionado.

Puede establecer estas propiedades en XAML o en el código, como se muestra aquí:

<ListView x:Name="myListView" SelectionMode="Multiple"/>

<GridView x:Name="myGridView" SelectionMode="None" IsItemClickEnabled="True"/>
myListView.SelectionMode = ListViewSelectionMode.Multiple;

myGridView.SelectionMode = ListViewSelectionMode.None;
myGridView.IsItemClickEnabled = true;

Solo lectura

Puede establecer la propiedad SelectionMode en ListViewSelectionMode.None para deshabilitar la selección de elementos. Esto coloca el control en modo de solo lectura para que se use para mostrar los datos, pero no para interactuar con ellos. Es decir, la selección de elementos está deshabilitada, pero el propio control no lo está.

Selección única

En esta tabla se describen las interacciones de teclado, mouse y entrada táctil cuando SelectionMode está establecido en Single.

Tecla modificadora Interacción
Ninguno
  • Los usuarios pueden seleccionar un solo elemento mediante la barra espaciadora, los clics del mouse o las pulsaciones.
  • Ctrl
  • Los usuarios pueden anular la selección de un solo elemento mediante la barra espaciadora, los clics del mouse o las pulsaciones.
  • Con las teclas de dirección, los usuarios pueden mover el foco independientemente de la selección.
  • Cuando SelectionMode se establece en Single, puede obtener el elemento de datos seleccionado de la propiedad SelectedItem . Puede obtener el índice en la colección del elemento seleccionado mediante la propiedad SelectedIndex . Si no se selecciona ningún elemento, SelectedItem es NULL y SelectedIndex es -1.

    Si intenta establecer un elemento que no está en la colección Items como SelectedItem, la operación se omite y SelectedItem es null. Sin embargo, si intenta establecer SelectedIndex en un índice que está fuera del intervalo de los elementos de la lista, se produce una excepción System.ArgumentException.

    Selección múltiple

    En esta tabla se describen las interacciones de teclado, mouse y entrada táctil cuando SelectionMode está establecido en Multiple.

    Tecla modificadora Interacción
    Ninguno
  • Los usuarios pueden seleccionar varios elementos mediante la barra espaciadora, los clics del mouse o las pulsaciones para seleccionar el elemento centrado.
  • Con las teclas de dirección, los usuarios pueden mover el foco independientemente de su selección.
  • Shift
  • Un usuario puede seleccionar varios elementos contiguos haciendo clic o pulsando el primer elemento de la selección y luego el último elemento de la selección.
  • Con las teclas de dirección, los usuarios pueden seleccionar elementos contiguos a partir del elemento seleccionado si presionan la tecla Mayús.
  • Selección extendida

    En esta tabla se describen las interacciones de teclado, mouse y entrada táctil cuando SelectionMode está establecido en Extendido.

    Tecla modificadora Interacción
    Ninguno
  • El comportamiento es el mismo que la selección única .
  • Ctrl
  • Los usuarios pueden seleccionar varios elementos mediante la barra espaciadora, los clics del mouse o las pulsaciones para seleccionar el elemento centrado.
  • Con las teclas de dirección, los usuarios pueden mover el foco independientemente de la selección.
  • Shift
  • Un usuario puede seleccionar varios elementos contiguos haciendo clic o pulsando el primer elemento de la selección y luego el último elemento de la selección.
  • Con las teclas de dirección, los usuarios pueden seleccionar elementos contiguos a partir del elemento seleccionado si presionan la tecla Mayús.
  • Cuando SelectionMode se establece en Multiple o Extended, puede obtener los elementos de datos seleccionados de la propiedad SelectedItems .

    Las propiedades SelectedIndex, SelectedItem y SelectedItems se sincronizan. Por ejemplo, si establece SelectedIndex en -1, SelectedItem se establece en NULL y SelectedItems está vacío. Y si establece SelectedItem en null, SelectedIndex se establece en -1 y SelectedItems está vacío.

    En el modo de selección múltiple, SelectedItem contiene el elemento que se seleccionó primero y Selectedindex contiene el índice del elemento que se seleccionó primero.

    Responder a los cambios de selección

    Para responder a cambios de selección en una vista de lista, controla el evento SelectionChanged. En el código del controlador de eventos, puedes obtener la lista de elementos seleccionados a partir de la propiedad SelectionChangedEventArgs.AddedItems. Puedes obtener los elementos cuya selección se anuló a partir de la propiedad SelectionChangedEventArgs.RemovedItems. Las colecciones AddedItems y RemovedItems contienen como máximo un elemento, a menos que los usuarios seleccionen un intervalo de elementos manteniendo presionada la tecla Mayús.

    En el ejemplo siguiente se muestra cómo controlar el evento SelectionChanged y acceder a las distintas colecciones Item:

    <StackPanel HorizontalAlignment="Right">
        <ListView x:Name="listView1" SelectionMode="Multiple"
                  SelectionChanged="ListView1_SelectionChanged">
            <x:String>Apricot</x:String>
            <x:String>Banana</x:String>
            <x:String>Cherry</x:String>
            <x:String>Orange</x:String>
            <x:String>Strawberry</x:String>
        </ListView>
        <TextBlock x:Name="selectedItem"/>
        <TextBlock x:Name="selectedIndex"/>
        <TextBlock x:Name="selectedItemCount"/>
        <TextBlock x:Name="addedItems"/>
        <TextBlock x:Name="removedItems"/>
    </StackPanel>
    
    private void ListView1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (listView1.SelectedItem != null)
        {
            selectedItem.Text =
                "Selected item: " + listView1.SelectedItem.ToString();
        }
        else
        {
            selectedItem.Text =
                "Selected item: null";
        }
        selectedIndex.Text =
            "Selected index: " + listView1.SelectedIndex.ToString();
        selectedItemCount.Text =
            "Items selected: " + listView1.SelectedItems.Count.ToString();
        addedItems.Text =
            "Added: " + e.AddedItems.Count.ToString();
        removedItems.Text =
            "Removed: " + e.RemovedItems.Count.ToString();
    }
    

    Modo de clic

    Puede cambiar una vista de lista para que los usuarios hagan clic en botones y otros elementos en lugar de seleccionarlos. Por ejemplo, esto resulta útil si la aplicación abre una nueva página cuando los usuarios hacen clic en un elemento de una lista o cuadrícula.

    Para habilitar este comportamiento:

    • Establezca SelectionMode en Ninguno.
    • Establezca IsItemClickEnabled en True.
    • Controla el evento ItemClick para hacer algo cuando los usuarios hacen clic en un elemento.

    Esta es una vista de lista con elementos que se pueden hacer clic. El código del controlador de eventos ItemClick abre una página nueva en la aplicación.

    <ListView SelectionMode="None"
              IsItemClickEnabled="True"
              ItemClick="ListView1_ItemClick">
        <x:String>Page 1</x:String>
        <x:String>Page 2</x:String>
        <x:String>Page 3</x:String>
        <x:String>Page 4</x:String>
        <x:String>Page 5</x:String>
    </ListView>
    
    private void ListView1_ItemClick(object sender, ItemClickEventArgs e)
    {
        switch (e.ClickedItem.ToString())
        {
            case "Page 1":
                this.Frame.Navigate(typeof(Page1));
                break;
    
            case "Page 2":
                this.Frame.Navigate(typeof(Page2));
                break;
    
            case "Page 3":
                this.Frame.Navigate(typeof(Page3));
                break;
    
            case "Page 4":
                this.Frame.Navigate(typeof(Page4));
                break;
    
            case "Page 5":
                this.Frame.Navigate(typeof(Page5));
                break;
    
            default:
                break;
        }
    }
    

    Selección de un intervalo de elementos mediante programación

    A veces, es posible que tenga que manipular una selección de elementos ListView mediante programación. Por ejemplo, puede mostrar un botón Seleccionar todo para permitir que los usuarios seleccionen todos los elementos de una lista. En este caso, normalmente no resulta muy eficaz agregar y quitar elementos de la colección SelectedItems uno por uno. Cada cambio de elemento provoca un evento SelectionChanged y, cuando se trabaja con los elementos directamente en lugar de trabajar con valores de índice, el elemento se des virtualiza.

    Es más eficaz usar los métodos SelectAll, SelectRange y DeselectRange para modificar la selección que para usar la propiedad SelectedItems. Estos métodos seleccionan (o anulan la selección) de elementos mediante intervalos de índices de elementos. Los elementos virtualizados permanecen virtualizados, ya que solo se usa el índice. Todos los elementos del intervalo especificado se seleccionan (o se deseleccionan), independientemente de su estado de selección original. El evento SelectionChanged se produce una sola vez para cada llamada a estos métodos.

    Importante

    Solo debe llamar a estos métodos cuando la propiedad SelectionMode esté establecida en Multiple o Extended. Si llama a SelectRange cuando SelectionMode es Single o None, se produce una excepción.

    Al seleccionar elementos mediante intervalos de índice, use la propiedad SelectedRanges para obtener todos los intervalos seleccionados de la lista.

    Si la propiedad ItemsSource implementa IItemsRangeInfo y usa estos métodos para modificar la selección, las propiedades AddedItems y RemovedItems no se establecen en SelectionChangedEventArgs. Establecer estas propiedades requiere la des virtualización del objeto de elemento. Utilice la propiedad SelectedRanges para obtener los elementos en su lugar.

    Para seleccionar todos los elementos en una colección, puede llamar al método SelectAll. Sin embargo, no hay ningún método correspondiente para anular la selección de todos los elementos. Para anular la selección de todos los elementos, puedes llamar a DeselectRange y pasar una clase ItemIndexRange con un valor FirstIndex de 0 y un valor Length igual al número de elementos de la colección. Esto se muestra en el ejemplo siguiente, junto con una opción para seleccionar todos los elementos.

    <StackPanel Width="160">
        <Button Content="Select all" Click="SelectAllButton_Click"/>
        <Button Content="Deselect all" Click="DeselectAllButton_Click"/>
        <ListView x:Name="listView1" SelectionMode="Multiple">
            <x:String>Apricot</x:String>
            <x:String>Banana</x:String>
            <x:String>Cherry</x:String>
            <x:String>Orange</x:String>
            <x:String>Strawberry</x:String>
        </ListView>
    </StackPanel>
    
    private void SelectAllButton_Click(object sender, RoutedEventArgs e)
    {
        if (listView1.SelectionMode == ListViewSelectionMode.Multiple ||
            listView1.SelectionMode == ListViewSelectionMode.Extended)
        {
            listView1.SelectAll();
        }
    }
    
    private void DeselectAllButton_Click(object sender, RoutedEventArgs e)
    {
        if (listView1.SelectionMode == ListViewSelectionMode.Multiple ||
            listView1.SelectionMode == ListViewSelectionMode.Extended)
        {
            listView1.DeselectRange(new ItemIndexRange(0, (uint)listView1.Items.Count));
        }
    }
    

    Para obtener información sobre cómo cambiar la apariencia de los elementos seleccionados, consulta Plantillas y contenedores de elementos.

    Arrastrar y colocar

    Los controles ListView y GridView admiten arrastrar y colocar elementos dentro de sus propios controles, y entre ellos y otros controles ListView y GridView. Para obtener más información sobre cómo implementar la funcionalidad de arrastrar y colocar, consulta Arrastrar y colocar.

    Obtener el código de ejemplo