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

Большая часть приложений отображает наборы данных, такие как коллекции изображений или набор сообщений электронной почты, и управляет ими. Платформа пользовательского интерфейса 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

Важно!

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

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

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

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

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

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

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

Элементы управления ListView и GridView относятся к типу ItemsControl, поэтому они могут содержать коллекцию элементов любого типа. Элемент управления ListView или GridView должен содержать элементы в коллекции Items , прежде чем он сможет отображать что-либо на экране. Чтобы заполнить представление, можно добавить элементы непосредственно в коллекцию или задать для свойства 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 задано значение Несколько.

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

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

    Клавиша-модификатор Тип взаимодействия
    Нет
  • Поведение схоже с выделением Single.
  • Ctrl
  • Пользователи могут выбрать несколько элементов с помощью пробела, щелчков мышью или касаний, чтобы выбрать элемент с фокусом.
  • С помощью клавиш со стрелками пользователи могут перемещать фокус независимо от выделенного фрагмента.
  • Сдвиг
  • Пользователи могут выбрать несколько смежных элементов, щелкнув или коснувшись первого элемента в выделенном фрагменте, а затем щелкнув или коснувшись последнего элемента в выделенном фрагменте.
  • С помощью клавиш со стрелками пользователи могут выбирать смежные элементы, начиная с элемента, выбранного при нажатии клавиши SHIFT.
  • Если параметр SelectionMode имеет значение Несколько или Расширенный, вы можете получить выбранные элементы данных из свойства 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 и получить доступ к различным коллекциям 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();
    }
    

    Режим щелчка

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

    Включить такое поведение:

    • Задайте для 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. Дополнительные сведения о реализации функций перетаскивания см. в разделе Перетаскивание.

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