Представления списка и сетки

Большинство приложений управляют наборами данных и отображают наборы данных, например коллекцию изображений или набор сообщений электронной почты. Платформа пользовательского интерфейса XAML предоставляет элементы управления ListView и GridView, которые упрощают отображение и управление данными в приложении.

Примечание.

ListView и GridView являются производными от класса ListViewBase , поэтому они имеют одинаковые функциональные возможности, но отображают данные по-разному. В этой статье обсуждения о представлении списка применяются как к элементам управления ListView, так и к GridView, если иное не указано. Когда упоминаются классы ListView или ListViewItem, нужно помнить, что префикс List может быть заменен префиксом Grid для соответствующего эквивалента сетки (GridView или GridViewItem).

Элементы управления ListView и GridView предоставляют множество преимуществ при работе с коллекциями. Обе функции легко реализовать и предоставить базовый пользовательский интерфейс, взаимодействие и прокрутку при легкой настройке. И оба могут быть привязаны к существующим динамическим источникам данных или к жестко закодированных данных, предоставляемых в самом XAML или коде программной части.

Оба элемента управления являются гибкими для использования в различных сценариях, но в целом они лучше всего работают с коллекциями, в которых все элементы имеют одинаковую базовую структуру и внешний вид, а также одинаковое поведение взаимодействия. То есть все они должны выполнять одно и то же действие при щелчке (например, чтобы открыть ссылку или обзор).

Сравнение ListView и GridView

ListView

Элемент управления ListView отображает данные с накоплением по вертикали в одном столбце. ListView лучше подходит для элементов, имеющих текст в качестве фокуса, и для коллекций, которые должны быть считываются сверху вниз (например, в алфавитном порядке). Несколько распространенных вариантов использования ListView включают в себя списки сообщений и результатов поиска. Если необходимо отобразить коллекции в нескольких столбцах или в формате, например таблицу, не следует использовать ListView. Вместо этого рекомендуется использовать элемент управления DataGrid .

Снимок экрана: представление списка данных, сгруппированных по алфавиту.

GridView

Элемент управления GridView представляет коллекцию элементов в строках и столбцах, которые можно прокручивать по вертикали. Данные стекаются по горизонтали, пока не заполняет столбец, а затем продолжается следующая строка в столбце. GridView лучше подходит для коллекций с изображениями в качестве фокус-точки или элементов, которые можно считывать с боковой стороны или не отсортировать в определенном порядке. Распространенным вариантом использования GridView является коллекция фотографий или продуктов.

Снимок экрана: библиотека содержимого фотографий, отображаемая в виде представления сетки.

Какой элемент управления коллекциями следует использовать? Сравнение с ItemsRepeater

Важно понимать различия между этими типами элементов управления перед решением о том, какой из них следует использовать.

ListView и GridView

Элементы управления ListView и GridView с расширенными возможностями работают из поля. Они не требуют настройки, но их можно легко настроить. Каждый из них имеет собственный встроенный пользовательский интерфейс и интерфейс и предназначен для отображения почти любого типа коллекции как есть.

ItemsRepeater

Элемент управления ItemsRepeater также используется для отображения коллекций, но он разработан как стандартный блок для создания пользовательского элемента управления в соответствии с конкретными требованиями пользовательского интерфейса. Он не имеет одинаковых встроенных функций и функций, что и ListView и GridView, поэтому вам потребуется реализовать все необходимые функции или взаимодействия. Используйте ItemsRepeater, если у вас есть строго настроенный пользовательский интерфейс, который нельзя создать с помощью ListView или GridView, или если источник данных требует другого поведения для каждого элемента.

Дополнительные сведения о ItemsRepeater см. в документации по рекомендациям и API.

UWP и WinUI 2

Внимание

Сведения и примеры в этой статье оптимизированы для приложений, использующих пакет SDK для приложений Windows и WinUI 3, но обычно применимы к приложениям UWP, использующим WinUI 2. См. справочник по API UWP для конкретных сведений и примеров платформы.

В этом разделе содержатся сведения, необходимые для использования элемента управления в приложении UWP или WinUI 2.

API для этих элементов управления существуют в пространстве имен Windows.UI.Xaml.Controls .

  • API UWP: класс ListView, класс GridView, свойство ItemsSource, свойство Items
  • Откройте приложение коллекции WinUI 2 и просмотрите ListView или GridView в действии. Приложения из коллекции WinUI 2 включают интерактивные примеры большинства элементов управления, возможностей и функций WinUI 2. Получите приложение из Microsoft Store или получите исходный код в GitHub.

Мы рекомендуем использовать последнюю версию WinUI 2 , чтобы получить самые актуальные стили и шаблоны для всех элементов управления.

Создание представления списка или представления сетки

Откройте приложение коллекции WinUI 3 и просмотрите ListView или GridView в действии.

Приложение коллекции WinUI 3 включает интерактивные примеры большинства элементов управления, функций и функций WinUI 3. Получение приложения из Microsoft Store или получение исходного кода на GitHub

Элементы управления ListView и GridView относятся к типу ItemsControl, поэтому они могут содержать коллекцию элементов любого типа. Элемент управления ListView или GridView должен содержать элементы в коллекции "Элементы" , прежде чем он сможет отображать все элементы на экране. Чтобы заполнить представление, можно добавить элементы непосредственно в коллекцию или задать свойство ItemsSource источнику данных.

Внимание

Для заполнения списка можно использовать свойство Items или ItemsSource, но одновременно использовать их нельзя. Если задать свойство ItemsSource и добавить элемент в XAML, добавленный элемент игнорируется. Если задать свойство ItemsSource и добавить элемент в коллекцию Items в коде, создается исключение.

Многие примеры, приведенные в этой статье, заполняют коллекцию Items непосредственно для простоты. Тем не менее, это более распространено для элементов в списке, поступающих из динамического источника, таких как список книг из онлайн-базы данных. Для этой цели используется свойство ItemsSource.

Добавление элементов в элемент управления ListView или GridView

Элементы можно добавить в коллекцию элементов ListView или GridView с помощью XAML или кода, чтобы получить тот же результат. Обычно вы добавите элементы через XAML, если у вас есть небольшое количество элементов, которые не изменяются и легко определены, или если вы создаете элементы в коде во время выполнения.

Метод 1. Добавление элементов в коллекцию Items

  • Вариант 1. Добавление элементов с помощью 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>
    
  • Вариант 2. Добавление элементов с помощью кода

    <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);
    

Оба этих параметра создают одно и то же представление списка, как показано здесь:

Снимок экрана: простое представление списка, отображающее список фруктов.

Метод 2. Добавление элементов путем задания свойства ItemsSource

Обычно вы используете ListView или GridView для отображения данных из источника, например базы данных или Интернета. Чтобы заполнить элемент управления ListView или GridView из источника данных, задайте для свойства ItemsSource коллекцию элементов данных. Этот метод лучше работает, если ListView или GridView будет хранить объекты пользовательского класса, как показано в следующих примерах.

  • Вариант 1. Установка ItemsSource в коде

    Здесь свойство ListView ItemsSource задается в коде непосредственно экземпляру коллекции.

    <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);
    
  • Вариант 2. Установка ItemsSource в XAML

    Свойство ItemsSource можно также привязать к коллекции в XAML. Здесь ItemsSource привязан к общедоступному свойству с именем Contacts, которое предоставляет коллекцию частных данных страницы с именем _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"));
    }
    

Оба этих параметра будут создавать одно и то же представление списка, как показано на следующем снимке экрана. (Представление списка показывает строковое представление каждого элемента, так как шаблон данных не определен для этого упражнения.)

Снимок экрана: простое представление списка с набором свойств ItemsSource.

Внимание

Без определенного шаблона данных объекты пользовательского класса будут отображаться в представлении списка со своим строковым значением, только если у них есть определенный метод ToString .

Следующий раздел содержит более подробные сведения о том, как визуально представлять простые и настраиваемые элементы класса правильно в шаблоне ListView или GridView.

См.сведения о привязке данных.

Примечание.

Если необходимо отобразить сгруппированные данные в представлении списка, необходимо привязать к классу CollectionViewSource . CollectionViewSource выступает в качестве прокси-сервера для класса коллекции в XAML и обеспечивает поддержку группирования. Дополнительные сведения см. в разделе CollectionViewSource.

Настройка внешнего вида с помощью шаблона данных

С помощью шаблона данных в элементе управления ListView или GridView можно определить способ визуализации элементов и данных. По умолчанию элемент данных отображается в представлении списка в виде строки, представляющей объект данных, к которому он привязан. Чтобы отобразить строковое представление определенного свойства элемента данных, задав параметр DisplayMemberPath этому свойству.

Однако обычно может потребоваться показать более богатую презентацию данных. Чтобы указать способ отображения элементов в представлении списка или представлении сетки, создайте класс DataTemplate . XAML в DataTemplate определяет макет и внешний вид элементов управления, которые используются для отображения отдельного элемента. Элементы управления в макете могут быть привязаны к свойствам объекта данных или иметь статическое содержимое, определенное встроенное.

Внимание

При использовании расширения разметки x:Bind в DataTemplate необходимо указать тип данных (x:DataType) в шаблоне данных.

Простой шаблон данных ListView

В этом примере элемент данных является простой строкой. Чтобы добавить изображение слева от строки и отобразить строку в подростке, необходимо определить встроенный объект DataTemplate в определении ListView. Это тот же элемент управления ListView, который вы создали ранее с помощью параметра 1 в методе 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>

Вот как отображаются элементы данных при применении простого шаблона данных ListView:

Снимок экрана: список, отображаемый после применения простого шаблона данных ListView.

Шаблон данных ListView для объектов пользовательских классов

В следующем примере элемент данных является объектом Contact. Чтобы добавить изображение контакта слева от имени контакта и компании, необходимо определить встроенный объект DataTemplate в определении ListView. Этот шаблон данных ListView был создан в параметре 2 под методом 2, как показано ранее.

<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>

Вот как отображаются элементы данных при применении шаблона данных ListView для объектов пользовательского класса:

Снимок экрана: список, отображаемый после применения шаблона данных ListView для объектов пользовательского класса.

Шаблоны данных — это основной способ определения внешнего вида ListView. Они также могут значительно повлиять на производительность, если список содержит большое количество элементов.

Вы можете определить встроенный шаблон данных в определении ListView или GridView, как показано в предыдущем коде или отдельно в разделе "Ресурсы". Если вы определяете его за пределами определения ListView или GridView, необходимо предоставить шаблон данных атрибут x:Key и назначить его свойству ItemTemplate listView или GridView с помощью этого ключа.

Дополнительные сведения и примеры использования шаблонов данных и контейнеров элементов для определения внешнего вида элементов в списке или сетке см. в разделе Контейнеры элементов и шаблоны.

Изменение макета элементов

При добавлении элементов в элемент управления ListView или GridView автоматически упаковывает каждый элемент в контейнер элементов, а затем помещает все контейнеры элементов. Способ размещения контейнеров элементов зависит от свойства ItemsPanel элемента управления.

  • ListView по умолчанию использует ItemsStackPanel, который создает вертикальный список:

    Снимок экрана: простое представление списка, отображающее вертикальный список элементов.

  • GridView использует ItemsWrapGrid, который добавляет элементы по горизонтали, а также выполняет обтекание и прокрутку по вертикали:

    Снимок экрана: простое представление сетки с горизонтальным списком элементов.

Вы можете изменить макет элементов, изменив свойства на панели элементов или заменив панель по умолчанию на другую панель.

Примечание.

При изменении ItemsPanel не отключайте виртуализацию. Как ItemsStackPanel, так и ItemsWrapGrid поддерживают виртуализацию, поэтому эти классы безопасны для использования. Если вы используете любую другую панель, вы можете отключить виртуализацию и замедлить производительность представления списка. Дополнительные сведения см. в статьях представления списка в разделе "Производительность".

В этом примере показано, как сделать элемент управления ListView разместить контейнеры элементов в горизонтальном списке, изменив свойство Orientation объекта ItemsStackPanel.

Так как представление списка прокручивается по вертикали, по умолчанию также необходимо настроить некоторые свойства во внутреннем представлении списка ScrollViewer , чтобы сделать его горизонтально прокручиваемым.

Внимание

Ниже приведены примеры, в которых ширина представления списка не ограничена, поэтому горизонтальные полосы прокрутки не отображаются. При запуске этого кода можно задать Width="180" для ListView отображение полос прокрутки.

<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>

Вот как отображается список:

Снимок экрана: горизонтальное представление списка.

В следующем примере ListView помещает элементы в список вертикальной упаковки с помощью ItemsWrapGrid вместо ItemsStackPanel.

Внимание

Чтобы принудительно упаковать контейнеры, необходимо ограничить высоту представления списка.

<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>

Вот как отображается список:

Снимок экрана: представление списка с макетом сетки.

Если в представлении списка отображаются сгруппированные данные, ItemsPanel определяет, как выкладываются группы элементов, а не как выкладываются отдельные элементы. Например, если вы используете ранее показанный горизонтальный ItemsStackPanel для отображения сгруппированных данных, группы упорядочиются по горизонтали, но элементы в каждой группе по-прежнему стекаются по вертикали, как показано здесь:

Снимок экрана: сгруппированное горизонтальное представление списка..

Выбор и взаимодействие элементов

Вы можете выбрать различные способы взаимодействия пользователей с представлением списка. По умолчанию пользователи могут выбрать один элемент. Можно изменить свойство SelectionMode, чтобы разрешить выбор нескольких элементов или отключить их выбор. Свойство IsItemClickEnabled можно задать таким образом, чтобы пользователи нажимали элемент (например, кнопку), чтобы вызвать действие вместо выбора элемента.

Примечание.

И ListView, и GridView используют перечисление ListViewSelectionMode для свойств SelectionMode . IsItemClickEnabled имеет значение False по умолчанию, поэтому его необходимо задать только для включения режима щелчка.

В этой таблице показаны способы взаимодействия пользователя с представлением списка и способами реагирования на это взаимодействие.

Чтобы включить это взаимодействие, выполните следующие действия. Используйте следующие параметры. Обработка этого события: Используйте это свойство для получения выбранного элемента:
Нет взаимодействия SelectionMode="None"
IsItemClickEnabled="False"
Неприменимо Неприменимо
Один выбор SelectionMode="Single"
IsItemClickEnabled="False"
SelectionChanged SelectedItem
SelectedIndex
Несколько выборок SelectionMode="Multiple"
IsItemClickEnabled="False"
SelectionChanged SelectedItems
Расширенный выбор SelectionMode="Extended"
IsItemClickEnabled="False"
SelectionChanged SelectedItems
Щелчок SelectionMode="None"
IsItemClickEnabled="True"
ItemClick Неприменимо

Примечание.

Вы можете включить IsItemClickEnabled для создания события ItemClick, пока SelectionMode также имеет значение Single, Multiple или Extended. Если это сделать, событие ItemClick вызывается сначала, а затем вызывается событие SelectionChanged. В некоторых случаях (например, если перейти на другую страницу в обработчике событий ItemClick), событие SelectionChanged не вызывается, а элемент не выбран.

Эти свойства можно задать в XAML или коде, как показано ниже:

<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;

Только для чтения

Свойство SelectionMode можно задать для ListViewSelectionMode.None , чтобы отключить выделение элементов. Это помещает элемент управления в режим только для чтения, чтобы он использовался для отображения данных, но не для взаимодействия с ним. То есть выбор элемента отключен, но сам элемент управления не является.

Один выбор

В этой таблице описывается взаимодействие клавиатуры, мыши и сенсорного ввода, если параметр SelectionMode имеет значение Single.

Ключ модификатора Взаимодействие
нет
  • Пользователи могут выбрать один элемент с помощью панели пробела, щелчков мыши или касаний.
  • Ctrl
  • Пользователи могут отменить выбор одного элемента с помощью панели пробела, щелчков мыши или касаний.
  • С помощью клавиш со стрелками пользователи могут перемещать фокус независимо от выделения.
  • Если параметр SelectionMode имеет значение Single, вы можете получить выбранный элемент данных из свойства SelectedItem . Индекс можно получить в коллекции выбранного элемента с помощью свойства SelectedIndex . Если элемент не выбран, SelectedItem имеет значение NULL и SelectedIndex равно -1.

    Если вы пытаетесь задать элемент, который не находится в коллекции Items в качестве SelectedItem, операция игнорируется, и SelectedItem имеет значение NULL. Однако при попытке задать SelectedIndex индекс, который выходит за пределы диапазона элементов в списке, возникает исключение System.ArgumentException.

    Несколько выборок

    В этой таблице описывается взаимодействие клавиатуры, мыши и сенсорного ввода, если параметр SelectionMode имеет значение Multiple.

    Ключ модификатора Взаимодействие
    нет
  • Пользователи могут выбрать несколько элементов с помощью панели пробела, щелчков мыши или касаний, чтобы выбрать элемент с фокусом.
  • С помощью клавиш со стрелками пользователи могут перемещать фокус независимо от выделенного фрагмента.
  • Shift
  • Пользователи могут выбрать несколько смежных элементов, щелкнув или коснувшись первого элемента в выделенном элементе, а затем щелкнув последний элемент в выделенном элементе.
  • С помощью клавиш со стрелками пользователи могут выбирать смежные элементы, начиная с выбранного элемента при выборе клавиши SHIFT.
  • Расширенный выбор

    В этой таблице описывается взаимодействие клавиатуры, мыши и сенсорного ввода, если параметр SelectionMode имеет значение Extended.

    Ключ модификатора Взаимодействие
    нет
  • Поведение совпадает с одним выделением.
  • Ctrl
  • Пользователи могут выбрать несколько элементов с помощью панели пробела, щелчков мыши или касаний, чтобы выбрать элемент с фокусом.
  • С помощью клавиш со стрелками пользователи могут перемещать фокус независимо от выделения.
  • Shift
  • Пользователи могут выбрать несколько смежных элементов, щелкнув или коснувшись первого элемента в выделенном элементе, а затем щелкнув последний элемент в выделенном элементе.
  • С помощью клавиш со стрелками пользователи могут выбирать смежные элементы, начиная с выбранного элемента при выборе клавиши SHIFT.
  • Если параметр SelectionMode имеет значение Multiple или Extended, вы можете получить выбранные элементы данных из свойства SelectedItems .

    Свойства SelectedIndex, SelectedItem и SelectedItems синхронизируются. Например, если для параметра SelectedIndex задано значение -1, SelectedItem имеет значение NULL , а SelectedItems пуст. Если параметр SelectedItem имеет значение NULL, selectedIndex имеет значение -1, а SelectedItems пуст.

    В режиме с несколькими выборами SelectedItem содержит элемент, выбранный первым, и Selectedindex содержит индекс элемента, который был выбран первым.

    Реагирование на изменения выбора

    Для того, чтобы реагировать на изменения в выборе элементов представления списка, используйте событие SelectionChanged. В коде обработчика этого события вы можете получить список выбранных элементов, используя свойство SelectionChangedEventArgs.AddedItems. Можно получить любые элементы, выбор которых был отменен, в свойстве SelectionChangedEventArgs.RemovedItems. Коллекции AddedItems и RemovedItems содержат не более одного элемента, если пользователи не выбирают диапазон элементов, удерживая клавишу SHIFT.

    В следующем примере показано, как обрабатывать событие SelectionChanged и получать доступ к различным коллекциям элементов:

    <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();
    }
    

    Режим щелчка

    Вы можете изменить представление списка, чтобы пользователи нажимали кнопки и другие элементы, а не выбирать их. Например, это полезно, если приложение открывает новую страницу при щелчке элемента в списке или сетке.

    Чтобы включить это поведение, выполните указанные ниже действия.

    • Задайте для параметра SelectionMode значение None.
    • Задайте для IsItemClickEnabled значение True.
    • Обработайте событие ItemClick, чтобы сделать что-то, когда пользователи щелкают элемент.

    Ниже приведено представление списка с элементами, которые можно щелкнуть. Код в обработчике событий ItemClick открывает новую страницу в приложении.

    <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;
        }
    }
    

    Выбор диапазона элементов программным способом

    Иногда может потребоваться управлять выбором элемента ListView программным способом. Например, можно отобразить кнопку "Выбрать все ", чтобы пользователи могли выбирать все элементы в списке. В этом случае обычно не очень эффективно добавлять и удалять элементы из коллекции SelectedItems по одному. Каждое изменение элемента приводит к возникновению события SelectionChanged и при работе с элементами непосредственно вместо работы со значениями индекса элемент де виртуализирован.

    Более эффективно использовать методы SelectAll, SelectRange и DeselectRange, чтобы изменить выбор, чем использовать свойство SelectedItems. Эти методы выбирают элементы (или отменяют выбор) с помощью диапазонов индексов элементов. Элементы, виртуализированные остаются виртуализированными, так как используется только индекс. Все элементы в указанном диапазоне выбираются (или отбираются), независимо от их исходного состояния выделения. Событие SelectionChanged происходит только один раз для каждого вызова этих методов.

    Внимание

    Эти методы следует вызывать только в том случае, если для свойства SelectionMode задано значение Multiple или Extended. Если вы вызываете SelectRange, когда SelectionMode имеет значение Single или None, создается исключение.

    При выборе элементов с помощью диапазонов индексов используйте свойство SelectedRanges , чтобы получить все выбранные диапазоны в списке.

    Если свойство ItemsSource реализует IItemsRangeInfo и используете эти методы для изменения выделения, свойства AddedItems и RemovedItems не задаются в SelectionChangedEventArgs. Установка этих свойств требует де-виртуализации объекта элемента. Используйте свойство SelectedRanges, чтобы получить элементы.

    Вы можете выбрать все элементы в коллекции, вызвав метод SelectAll. Однако нет соответствующего метода для отмены выбора всех элементов. Можно отменить выбор всех элементов, вызвав DeselectRange и передав ItemIndexRange со свойством FirstIndex, значение которого равно 0, и значением Length, равным числу элементов в коллекции. Это показано в следующем примере, а также параметр для выбора всех элементов.

    <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));
        }
    }
    

    Сведения о порядке изменения внешнего вида выбранных элементов см. в разделе Контейнеры и шаблоны элементов.

    Перетаскивание

    Элементы управления ListView и GridView поддерживают перетаскивание элементов в собственных элементах управления, а также между собой и другими элементами управления ListView и GridView. Дополнительные сведения о реализации функций перетаскивания см. в разделе "Перетаскивание".

    Получение кода примера

    • Пример XAML ListView и GridView: демонстрирует элементы управления ListView и GridView.
    • Пример перетаскивания XAML: демонстрирует перетаскивание с помощью элемента управления ListView.
    • Пример коллекции WinUI. Просмотрите все элементы управления XAML в интерактивном формате.