列表视图和网格视图List view and grid view

大多数应用都会操纵和显示数据集,例如图像库或一组电子邮件。Most applications manipulate and display sets of data, such as a gallery of images or a set of email messages. XAML UI 框架提供了轻松显示和操控应用数据的 ListView 和 GridView 控件。The XAML UI framework provides ListView and GridView controls that make it easy to display and manipulate data in your app.

重要的 APIListView 类GridView 类ItemsSource 属性Items 属性Important APIs: ListView class, GridView class, ItemsSource property, Items property

备注

ListView 和 GridView 都从 ListViewBase 类派生,因此它们的功能相同,但数据显示方式不同。ListView and GridView both derive from the ListViewBase class, so they have the same functionality, but display data differently. 在本文中,涉及到列表视图时,信息适用于 ListView 和 GridView 控件,除非另行指定。In this article, when we talk about list view, the info applies to both the ListView and GridView controls unless otherwise specified. 我们可能会引用 ListView 或 ListViewItem 等类,但 List 前缀可使用相应网格等效项(GridView 或 GridViewItem)的 Grid 代替 。We may refer to classes like ListView or ListViewItem, but the List prefix can be replaced with Grid for the corresponding grid equivalent (GridView or GridViewItem).

ListView 和 GridView 提供使用集合的许多好处。ListView and GridView provide many benefits for working with collections. 它们都易于实施且提供基本 UI、交互和滚动,同时仍可以轻松自定义。They are both easy to implement and provide basic UI; interaction; and scrolling while still being easily customizable. ListView 和 GridView 可以绑定到现有的动态数据源,也可以绑定到 XAML 本身/代码隐藏中提供的硬编码数据。ListView and GridView can be bound to existing dynamic data sources, or hard-coded data provided in the XAML itself/the code-behind.

这两种控件可以灵活应用于许多用例,但总体来说最适合所有项必须具有相同基本结构和外观以及相同交互行为的集合 - 即单击时它们都应执行相同操作(打开链接、导航等)。These two controls are flexible to many use cases, but overall work best with collections in which all items should have the same basic structure and appearance, as well as the same interaction behavior - i.e. they should all perform the same action when clicked (open a link, navigate, etc).

ListView 和 GridView 之间的差异Differences between ListView and GridView

ListViewListView

ListView 采用垂直堆叠的方式在单个列中显示数据。The ListView displays data stacked vertically in a single column. ListView 更适用于将文本作为焦点的项以及应从上到下读取的集合(即按字母顺序排列)。ListView works better for items that have text as a focal point, and for collections that are meant to be read top to bottom (i.e. alphabetically ordered). ListView 的几个常见用例包括消息列表和搜索结果。A few common use cases for ListView include lists of messages and search results. 需要在多个列中显示的集合或以类似于表的格式显示的集合 不应使用 ListView,而应考虑改用 DataGridCollections that need to be displayed in multiple columns or in a table-like format should not use ListView, but should look into using a DataGrid instead.

具有分组数据的列表视图

GridViewGridView

GridView 显示可在行和列中垂直滚动的项目集合。The GridView presents a collection of items in rows and columns that can scroll vertically. 数据水平堆叠,直到填满列,然后继续执行下一行。Data is stacked horizontally until it fills the columns, then continues with the next row. GridView 更适用于将图像作为焦点的项,以及可从一侧到另一侧读取或未按特定顺序进行排序的集合。GridView works better for items that have images as their focal point, and for collections that can be read from side-to-side or are not sorted in a specific order. GridView 的一个常见用例是照片或产品库。A common use case for GridView is a photo or product gallery.

内容库示例

应使用哪个集合控件?Which collection control should you use? 与 ItemsRepeater 的比较A Comparison with ItemsRepeater

ListView 和 GridView 是显示任何集合的现成控件,具有自己的内置 UI 和用户体验。ListView and GridView are controls that work out-of-the-box to display any collection, with their own built-in UI and UX. ItemsRepeater 控件也用于显示集合,但作为构建基块创建,用于创建符合你的确切 UI 需要的自定义控件。The ItemsRepeater control also is used to display collections, but was created as a building block for creating a custom control that fits your exact UI needs. 下面列出了应影响你最终使用的控件的最重要的差异:The most important differences that should impact which control you end up using are below:

  • ListView 和 GridView 是功能丰富的控件,只需很少的自定义,但会提供大量的功能。ListView and GridView are feature-rich controls that require little customization but offer plenty. ItemsRepeater 构建基块可用于创建你自己的布局控件,它没有相同的内置功能 - 它需要你实施任何必需的功能或交互。ItemsRepeater is a building block to create your own layout control and does not have the same built in features and functionality - it requires you to implement any necessary features or interactions.
  • 如果你需要创建一个无法通过 ListView 或 GridView 创建的高度自定义 UI,或者你的数据源的每个项需要非常不同的行为,则应使用 ItemsRepeater。ItemsRepeater should be used if you have a highly custom UI that you can’t create using ListView or GridView, or if you have a data source that requires highly different behavior for each item.

通过阅读指南 API 文档页面,详细了解 ItemsRepeater。Learn more about ItemsRepeater by reading its Guidelines and API Documentation pages.

示例Examples

XAML 控件库XAML Controls Gallery
XAML controls gallery

如果已安装 XAML 控件库应用,请单击此处打开该应用,了解 ListViewGridView 的实际应用。If you have the XAML Controls Gallery app installed, click here to open the app and see the ListView or GridView in action.

创建 ListView 或 GridViewCreate a ListView or GridView

ListView 和 GridView 的类型都是 ItemsControl,因此它们可以包含任何类型的项的集合。ListView and GridView are both ItemsControl types, so they can contain a collection of items of any type. ListView 或 GridView 必须在自己的 Items 集合中有项,才能够在屏幕上显示内容。A ListView or GridView must have items in its Items collection before it can show anything on the screen. 若要填充视图,可以将项目直接添加到 Items 集合,或者将 ItemsSource 属性设置为数据源。To populate the view, you can add items directly to the Items collection, or set the ItemsSource property to a data source.

重要

可以使用 Items 或 ItemsSource 填充列表,但无法同时使用这两者。You can use either Items or ItemsSource to populate the list, but you can't use both at the same time. 如果你设置 ItemsSource 属性并使用 XAML 添加项目,将忽略添加的项目。If you set the ItemsSource property and you add an item in XAML, the added item is ignored. 如果 ItemsSource 属性已设置且使用代码向项集合中添加项,则会引发异常。If you set the ItemsSource property and you add an item to the Items collection in code, an exception is thrown.

为方便起见,本文中的许多示例直接填充了 Items 集合。Many of the examples in this article populate the Items collection directly for the sake of simplicity. 但是,列表中的项目来自于动态源的情况更常见,例如书籍列表来自于在线数据库。However, it's more common for the items in a list to come from a dynamic source, like a list of books from an online database. 出于此目的,使用 ItemsSource 属性。You use the ItemsSource property for this purpose.

将项添加到 ListView 或 GridViewAdd Items to a ListView or GridView

可以将项添加到 ListView 或 GridView 的 Items 集合中,使用 XAML 或代码生成相同的结果。You can add items to the ListView or GridView's Items collection using XAML or code to yield the same result. 在以下情况下通常通过 XAML 添加项:具有不更改且可以轻松定义的少量项,或者在运行时使用代码生成项。You typically add items through XAML if you have a small number of items that don't change and are easily defined, or if you generate the items in code at run time.

方法 1:将项添加到项集合Method 1: Add items to the Items Collection

选项 1:通过 XAML 添加项Option 1: Add Items through 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:通过 C# 添加项Option 2: Add Items through C#

C# 代码:C# Code:
// 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 (that you created in the corresponding XAML file).
FruitsPanel.Children.Add(Fruits); 
相应的 XAML 代码:Corresponding XAML Code:
<StackPanel Name="FruitsPanel"></StackPanel>

上述两个选项将生成相同的 ListView,如下所示:Both of the above options will result in the same ListView, which is shown below:

简单的列表视图 A simple list view
方法 2:通过设置 ItemsSource 添加项 Method 2: Add items by setting the ItemsSource

通常使用 ListView 或 GridView 显示源(例如数据库或 Internet)中的数据。You typically use a ListView or GridView to display data from a source such as a database or the Internet. 要填充数据源中的 ListView/GridView,请将其 ItemsSource 属性设置为数据项集合。To populate a ListView/GridView from a data source, you set its ItemsSource property to a collection of data items. 如果 ListView 或 GridView 要保存自定义类对象(如以下示例中所示),则此方法更好。This method works better if your ListView or GridView is going to hold custom class objects, as shown in the examples below.

选项 1:使用 C# 设置 ItemsSourceOption 1: Set ItemsSource in C#

此时,直接在代码中将列表视图的 ItemsSource 设置为集合实例。Here, the list view's ItemsSource is set in code directly to an instance of a collection.

C# 代码:C# Code:
// Class defintion 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 below, 
//the data could be pulled asynchronously from a database or the internet.
ObservableCollection<Contact> Contacts = new ObservableCollection<Contact>();

// Contact objects are created 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", "ABC Printers"));
Contacts.Add(new Contact("Jane", "Doe", "XYZ Refridgerators"));
Contacts.Add(new Contact("Santa", "Claus", "North Pole Toy Factory Inc."));

// Create a new ListView (or GridView) for the UI, add content by setting ItemsSource
ListView ContactsLV = new ListView();
ContactsLV.ItemsSource = Contacts;

// Add the ListView to a parent container in the visual tree (that you created in the corresponding XAML file)
ContactPanel.Children.Add(ContactsLV);
XAML 代码:XAML Code:
<StackPanel x:Name="ContactPanel"></StackPanel>

选项 2:使用 XAML 设置 ItemsSourceOption 2: Set ItemsSource in XAML

还可以将 ItemsSource 属性绑定到 XAML 中的集合。You can also bind the ItemsSource property to a collection in the XAML. 在此处,ItemsSource 绑定到名为 Contacts 并且公开 Page 的专用数据集合 _contacts 的公共属性。Here, the ItemsSource is bound to a public property named Contacts that exposes the Page's private data collection, _contacts.

XAMLXAML

<ListView x:Name="ContactsLV" ItemsSource="{x:Bind Contacts}"/>

C#C#

// Class defintion should be provided within the namespace being used, outside of any other classes.
// These two declarations belong outside of the main page class.
private ObservableCollection<Contact> _contacts = new ObservableCollection<Contact>();

public ObservableCollection<Contact> Contacts
{
    get { return this._contacts; }
}

// This method should be defined 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", "ABC Printers"));
    Contacts.Add(new Contact("Jane", "Doe", "XYZ Refridgerators"));
    Contacts.Add(new Contact("Santa", "Claus", "North Pole Toy Factory Inc."));
}

上述两个选项将生成相同的 ListView,如下所示。Both of the above options will result in the same ListView, shown below. ListView 只显示每个项的字符串表示形式,因为我们未提供数据模板。The ListView only shows the string representation of each item because we did not provide a data template.

具有 ItemsSource 集的简单列表视图

重要

如果不定义数据模板,自定义类对象将仅以 ListView 形式显示字符串值(如果有已定义的 ToString() 方法)。With no data template defined, custom class objects will only appear in the ListView with their string value if they have a defined ToString() method.

下一部分将详细介绍如何在 ListView 或 GridView 中恰当地直观表示简单的和自定义的类项。The next section will go into detail on how to visually represent simple and custom class items properly in a ListView or GridView.

有关数据绑定的详细信息,请参阅数据绑定概述For more info about data binding, see Data binding overview.

备注

如果需要在 ListView 中显示分组数据,必须绑定到 CollectionViewSourceIf you need to show grouped data in your ListView, you must bind to a CollectionViewSource. CollectionViewSource 在 XAML 中充当集合类的代理角色,并启用分组支持。The CollectionViewSource acts as a proxy for the collection class in XAML and enables grouping support. 有关详细信息,请参阅 CollectionViewSourceFor more info, see CollectionViewSource.

使用 DataTemplate 自定义项的外观Customizing the look of items with a DataTemplate

ListView 或 GridView 中的数据模板定义可视化项/数据的方式。A data template in a ListView or GridView defines how the items/data are visualized. 在默认情况下,数据项以绑定到的数据对象的字符串表现形式显示在 ListView 中。By default, a data item is displayed in the ListView as the string representation of the data object it's bound to. 通过将 DisplayMemberPath 设置到特定的属性,你可以显示数据项的特定属性的字符串表现形式。You can show the string representation of a particular property of the data item by setting the DisplayMemberPath to that property.

但是,你通常会希望更丰富地呈现你的数据。However, you typically want to show a more rich presentation of your data. 若要具体地指定 ListView/GridView 中项的显示方式,可以创建 DataTemplateTo specify exactly how items in the ListView/GridView are displayed, you create a DataTemplate. DataTemplate 中的 XAML 定义用于显示各项的控件的布局和外观。The XAML in the DataTemplate defines the layout and appearance of controls used to display an individual item. 该布局中的控件可绑定到数据对象的属性,或者具有在内联中定义的静态内容。The controls in the layout can be bound to properties of a data object, or have static content defined inline.

备注

在 DataTemplate 中使用 x:Bind 标记扩展时,必须指定 DataTemplate 中的 DataType (x:DataType)。When you use the x:Bind markup extension in a DataTemplate, you have to specify the DataType (x:DataType) on the DataTemplate.

简单的 ListView 数据模板Simple ListView Data Template

在此示例中,数据项是简单的字符串。In this example, the data item is a simple string. 数据模板在 ListView 定义中内联定义,将图像添加到字符串左侧,并用青色显示字符串。A DataTemplate is defined inline within the ListView definition to add an image to the left of the string, and show the string in teal. 这是使用上面所示的方法 1 和选项 1 创建的相同 ListView。This is the same ListView created from using Method 1 and Option 1 shown above.

XAMLXAML

<!--No corresponding C# 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 中通过此数据模板显示时数据项的外观:Here's what the data items look like when displayed with this data template in a ListView:

使用数据模板的 ListView 项目

自定义类对象的 ListView 数据模板ListView Data Template for Custom Class Objects

在此示例中,数据项是联系人对象。In this example, the data item is a Contact object. 数据模板在 ListView 定义中内联定义,将联系人图像添加到联系人名称和公司左侧。A DataTemplate is defined inline within the ListView definition to add the contact image to the left of the Contact name and company. 此 ListView 是使用上面提到的方法 2 和选项 2 创建的。This ListView was created by using Method 2 and Option 2 mentioned above.

<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 中通过此数据模板显示时数据项的外观:Here's what the data items look like when displayed using this data template in a ListView:

使用数据模板的 ListView 自定义类项

使用数据模板是定义 ListView 外观的主要方法。Data templates are the primary way you define the look of your ListView. 如果列表保留大量项目,它们也能对性能产生重大影响。They can also have a significant impact on performance if your list holds a large number of items.

数据模板可在 ListView/GridView 定义中内联定义(如上所示),也可以在“资源”部分单独定义。Your data template can be defined inline within the ListView/GridView definition (shown above), or separately in a Resources section. 如果数据模板在 ListView/GridView 外定义,则必须被赋予 x:Key 特性并赋给使用该键的 ListView 或 GridView 的 ItemTemplate 属性。If defined outside of the ListView/GridView itself, the DataTemplate must be given an x:Key attribute and be assigned to the ItemTemplate property of the ListView or GridView using that key.

有关如何使用数据模板和项目容器定义列表或网格中的项目的外观的更多信息和示例,请参阅项目容器和模板For more info and examples of how to use data templates and item containers to define the look of items in your list or grid, see Item containers and templates.

更改项的布局Change the layout of items

当你将项目添加到 ListView 或 GridView 时,控件会使每个项目在项目容器中自动换行,然后设置所有项目容器的布局。When you add items to a ListView or GridView, the control automatically wraps each item in an item container and then lays out all of the item containers. 这些项目容器的布局方式取决于控件的 ItemsPanelHow these item containers are laid out depends on the ItemsPanel of the control.

  • 默认情况下,“ListView”使用 ItemsStackPanel,这可以生成垂直列表,如下所示 。By default, ListView uses an ItemsStackPanel, which produces a vertical list, like this.

简单的列表视图

  • “GridView”使用 ItemsWrapGrid,这会水平添加项目,并且垂直换行和滚动,如下所示 。GridView uses an ItemsWrapGrid, which adds items horizontally, and wraps and scrolls vertically, like this.

简单的网格视图

你可以通过在项目面板上调整属性来修改项目布局,或者可以将默认面板替换为其他面板。You can modify the layout of items by adjusting properties on the items panel, or you can replace the default panel with another panel.

备注

如果更改 ItemsPanel,注意不要禁用虚拟化。Be careful to not disable virtualization if you change the ItemsPanel. ItemsStackPanelItemsWrapGrid 均支持虚拟化,所以可以安全使用它们。Both ItemsStackPanel and ItemsWrapGrid support virtualization, so these are safe to use. 如果你使用任何其他面板,可能会禁用虚拟化,并且降低列表视图的性能。If you use any other panel, you might disable virtualization and slow the performance of the list view. 有关详细信息,请参阅性能下的列表视图文章。For more info, see the list view articles under Performance.

此示例显示如何通过更改“ItemsStackPanel”的 Orientation 属性来使“ListView”在水平列表中设置项目容器的布局 。This example shows how to make a ListView lay out its item containers in a horizontal list by changing the Orientation property of the ItemsStackPanel. 因为默认情况下列表视图垂直滚动,所以你还需要在列表视图的内部 ScrollViewer 上调整某些属性以使其可以水平滚动。Because the list view scrolls vertically by default, you also need to adjust some properties on the list view’s internal ScrollViewer to make it scroll horizontally.

重要

显示这些示例时,列表视图宽度不受约束,因此不会显示水平滚动条。These examples are shown with the list view width unconstrained, so the horizontal scrollbars are not shown. 如果你运行此代码,可以在 ListView 上设置 Width="180" 来使滚动条显示。If you run this code, you can set Width="180" on the ListView to make the scrollbars show.

XAMLXAML

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

生成的列表如下所示。The resulting list looks like this.

水平列表视图

在下一个示例中,通过使用 ItemsWrapGrid 而非 ItemsStackPanelListView 在垂直换行列表中设置项目的布局。In the next example, the ListView lays out items in a vertical wrapping list by using an ItemsWrapGrid instead of an ItemsStackPanel.

重要

列表视图的高度必须受限,以强制控件使容器换行。The height of the list view must be constrained to force the control to wrap the containers.

XAMLXAML

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

生成的列表如下所示。The resulting list looks like this.

具有网格布局的列表视图

如果你在列表视图中显示分组数据,ItemsPanel 将确定项目组的布局方式,而非单独项目的布局方式。例如,如果之前显示的水平 ItemsStackPanel 用于显示分组数据,则各组按水平方式排列,但每组中的项目仍垂直堆叠,如下所示。If you show grouped data in your list view, the ItemsPanel determines how the item groups are layed out, not how the individual items are layed out. For example, if the horizontal ItemsStackPanel shown previously is used to show grouped data, the groups are arranged horizontally, but the items in each group are still stacked vertically, as shown here.

已分组的水平列表视图

项目选择和交互Item selection and interaction

你可以选择多种方法来使用户与列表视图交互。You can choose from various ways to let a user interact with a list view. 默认情况下,用户可选择一个项目。By default, a user can select a single item. 你可以更改 SelectionMode 属性以启用多选或禁用选择。You can change the SelectionMode property to enable multi-selection or to disable selection. 你可以设置 IsItemClickEnabled 属性,以便用户单击某个项目即可调用操作(例如按钮),而不是选择该项目。You can set the IsItemClickEnabled property so that a user clicks an item to invoke an action (like a button) instead of selecting the item.

注意  ListView 和 GridView 均将 ListViewSelectionMode 枚举用于其 SelectionMode 属性。Note  Both ListView and GridView use the ListViewSelectionMode enumeration for their SelectionMode properties. 默认情况下,IsItemClickEnabled 为 False,因此你需要仅将其设置为启用单击模式。IsItemClickEnabled is False by default, so you need to set it only to enable click mode.

此表显示用户可与列表视图交互的方式以及响应交互的方式。This table shows the ways a user can interact with a list view, and how you can respond to the interaction.

若要启用此交互:To enable this interaction: 使用这些设置:Use these settings: 处理此事件:Handle this event: 使用此属性以获取选定的项目:Use this property to get the selected item:
无交互No interaction SelectionMode = NoneIsItemClickEnabled = FalseSelectionMode = None, IsItemClickEnabled = False N/AN/A N/AN/A
单选Single selection SelectionMode = Single、IsItemClickEnabled = FalseSelectionMode = Single, IsItemClickEnabled = False SelectionChangedSelectionChanged SelectedItemSelectedIndexSelectedItem, SelectedIndex
多选Multiple selection SelectionMode = Multiple、IsItemClickEnabled = FalseSelectionMode = Multiple, IsItemClickEnabled = False SelectionChangedSelectionChanged SelectedItemsSelectedItems
扩展选择Extended selection SelectionMode = Extended、IsItemClickEnabled = FalseSelectionMode = Extended, IsItemClickEnabled = False SelectionChangedSelectionChanged SelectedItemsSelectedItems
单击Click SelectionMode = None、IsItemClickEnabled = TrueSelectionMode = None, IsItemClickEnabled = True ItemClickItemClick N/AN/A

注意  从 Windows 10 开始,可启用 IsItemClickEnabled 来引发 ItemClick 事件,同时 SelectionMode 也可设置为 Single、Multiple 或 Extended。Note  Starting in Windows 10, you can enable IsItemClickEnabled to raise an ItemClick event while SelectionMode is also set to Single, Multiple, or Extended. 如果你执行此操作,将先后引发 ItemClick 事件和 SelectionChanged 事件。If you do this, the ItemClick event is raised first, and then the SelectionChanged event is raised. 在某些情况下(例如在 ItemClick 事件处理程序中导航到其他页面),不会引发 SelectionChanged 事件,并且不会选择该项目。In some cases, like if you navigate to another page in the ItemClick event handler, the SelectionChanged event is not raised and the item is not selected.

可以采用 XAML 或代码设置这些属性,如下所示。You can set these properties in XAML or in code, as shown here.

XAMLXAML

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

<GridView x:Name="myGridView" SelectionMode="None" IsItemClickEnabled="True"/> 

C#C#

myListView.SelectionMode = ListViewSelectionMode.Multiple; 

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

只读Read-only

你可以将 SelectionMode 属性设置为 ListViewSelectionMode.None 以禁用项目选择。You can set the SelectionMode property to ListViewSelectionMode.None to disable item selection. 这会将控件置于只读模式下、使之用于显示数据,但不是为了与之交互。This puts the control in read only mode, to be used for displaying data, but not for interacting with it. 控件本身不会被禁用,仅禁用项目选择。The control itself is not disabled, only item selection is disabled.

单选Single selection

下表介绍在 SelectionMode 设置为 Single 时,键盘、鼠标和触摸的交互情况。This table describes the keyboard, mouse, and touch interactions when SelectionMode is Single.

修改键Modifier key 交互Interaction
None
  • 用户可以使用空格键、鼠标单击或触摸点击来选择单个项。A user can select a single item using the space bar, mouse click, or touch tap.
  • CtrlCtrl
  • 用户可以使用空格键、鼠标单击或触摸点击来取消选择单个项。A user can deselect a single item using the space bar, mouse click, or touch tap.
  • 通过使用箭头键,用户可以独立于选择来移动焦点。Using the arrow keys, a user can move focus independently of selection.
  • 当 SelectionMode 设置为“Single”时,可以从 SelectedItem 属性获取选定的数据项 。When SelectionMode is Single, you can get the selected data item from the SelectedItem property. 你可以使用 SelectedIndex 属性获取选定项目集合中的索引。You can get the index in the collection of the selected item using the SelectedIndex property. 如果没有选择任何项目,则 SelectedItem 为 null,并且 SelectedIndex 为 -1。If no item is selected, SelectedItem is null, and SelectedIndex is -1.

    如果你尝试设置像 SelectedItem 那样不在 Items 集合中的项目,则该操作将被忽略,并且 SelectedItem 为 nullIf you try to set an item that is not in the Items collection as the SelectedItem, the operation is ignored and SelectedItem isnull. 但是,如果你尝试在列表中将 SelectedIndex 设置为超出 Items 范围的索引,将会发生 System.ArgumentException 异常。However, if you try to set the SelectedIndex to an index that's out of the range of the Items in the list, a System.ArgumentException exception occurs.

    多选Multiple selection

    下表介绍在 SelectionMode 设置为 Multiple 时,键盘、鼠标和触摸的交互情况。This table describes the keyboard, mouse, and touch interactions when SelectionMode is Multiple.

    修改键Modifier key 交互Interaction
    None
  • 用户可以使用空格键、鼠标单击或触摸点击来选择多个项目,以在聚焦项目上切换选择。A user can select multiple items using the space bar, mouse click, or touch tap to toggle selection on the focused item.
  • 通过使用箭头键,用户可以独立于选择来移动焦点。Using the arrow keys, a user can move focus independently of selection.
  • ShiftShift
  • 用户可以通过先后单击或点击选择中的第一个和最后一个项目来选择多个连续项目。A user can select multiple contiguous items by clicking or tapping the first item in the selection and then the last item in the selection.
  • 通过使用箭头键,用户可以创建从在按下 Shift 时选择的项目开始的连续选择。Using the arrow keys, a user can create a contiguous selection starting with the item selected when Shift is pressed.
  • 扩展选择Extended selection

    下表介绍在 SelectionMode 设置为 Extended 时,键盘、鼠标和触摸的交互情况。This table describes the keyboard, mouse, and touch interactions when SelectionMode is Extended.

    修改键Modifier key 交互Interaction
    None
  • 该行为与 Single 选择相同。The behavior is the same as Single selection.
  • CtrlCtrl
  • 用户可以使用空格键、鼠标单击或触摸点击来选择多个项目,以在聚焦项目上切换选择。A user can select multiple items using the space bar, mouse click, or touch tap to toggle selection on the focused item.
  • 通过使用箭头键,用户可以独立于选择来移动焦点。Using the arrow keys, a user can move focus independently of selection.
  • ShiftShift
  • 用户可以通过先后单击或点击选择中的第一个和最后一个项目来选择多个连续项目。A user can select multiple contiguous items by clicking or tapping the first item in the selection and then the last item in the selection.
  • 通过使用箭头键,用户可以创建从在按下 Shift 时选择的项目开始的连续选择。Using the arrow keys, a user can create a contiguous selection starting with the item selected when Shift is pressed.
  • 当 SelectionMode 设置为“Multiple”或“Extended”时,可以从 SelectedItems 属性获取选定的数据项 。When SelectionMode is Multiple or Extended, you can get the selected data items from the SelectedItems property.

    SelectedIndexSelectedItemSelectedItems 属性已同步。The SelectedIndex, SelectedItem, and SelectedItems properties are synchronized. 例如,如果你将 SelectedIndex 设置为 -1、将 SelectedItem 设置为 null 并且将 SelectedItems 设置为空;如果你将 SelectedItem 设置为 null、将 SelectedIndex 设置为 -1 并且将 SelectedItems 设置为空。For example, if you set SelectedIndex to -1, SelectedItem is set to null and SelectedItems is empty; if you set SelectedItem to null, SelectedIndex is set to -1 and SelectedItems is empty.

    在多选模式下,SelectedItem 包含第一个选择的项目,而 Selectedindex 包含第一个选择的项目的索引。In multi-select mode, SelectedItem contains the item that was selected first, and Selectedindex contains the index of the item that was selected first.

    响应选择更改Respond to selection changes

    若要响应列表视图中的选择更改,请处理 SelectionChanged 事件。To respond to selection changes in a list view, handle the SelectionChanged event. 在事件处理程序代码中,可以从 SelectionChangedEventArgs.AddedItems 属性获取选择项列表。In the event handler code, you can get the list of selected items from the SelectionChangedEventArgs.AddedItems property. 你可以获取从 SelectionChangedEventArgs.RemovedItems 属性取消选择的任何项目。You can get any items that were deselected from the SelectionChangedEventArgs.RemovedItems property. 除非用户通过按住 Shift 键选择项目范围,否则 AddedItems 和 RemovedItems 集合将最多包含 1 个项目。The AddedItems and RemovedItems collections contain at most 1 item unless the user selects a range of items by holding down the Shift key.

    此示例显示了如何处理 SelectionChanged 事件和访问各种项目集合。This example shows how to handle the SelectionChanged event and access the various items collections.

    XAMLXAML

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

    C#C#

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

    单击模式Click mode

    你可以更改列表视图,从而使用户单击项目(如按钮),而不是选择项目。You can change a list view so that a user clicks items like buttons instead of selecting them. 例如,当用户点击列表或网格中的一个项目时,如果你的应用导航至一个新页面,这将会很有用。For example, this is useful when your app navigates to a new page when your user clicks an item in a list or grid. 若要启用此行为:To enable this behavior:

    • SelectionMode 设置为 NoneSet SelectionMode to None.
    • IsItemClickEnabled 设置为 trueSet IsItemClickEnabled to true.
    • 在用户单击某个项目时,处理 ItemClick 事件以执行某些操作。Handle the ItemClick event to do something when your user clicks an item.

    下面是具有可单击项的列表视图。Here's a list view with clickable items. ItemClick 事件处理程序中的代码会导航到新的页面。The code in the ItemClick event handler navigates to a new page.

    XAMLXAML

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

    C#C#

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

    以编程方式选择项目的范围Select a range of items programmatically

    有时你需要以编程方式来操控列表视图的项目选择。Sometimes, you need to manipulate a list view’s item selection programmatically. 例如,你可能拥有“全选” 按钮来让用户选择列表中的所有项目。For example, you might have a Select all button to let a user select all items in a list. 在这种情况下,从 SelectedItems 集合逐个添加或删除项目通常效率不高。In this case, it’s usually not very efficient to add and remove items from the SelectedItems collection one by one. 每个项目更改都会导致发生 SelectionChanged 事件,并且当你直接处理项目而非索引值时,该项目会取消虚拟化。Each item change causes a SelectionChanged event to occur, and when you work with the items directly instead of working with index values, the item is de-virtualized.

    SelectAllSelectRangeDeselectRange 方法提供比使用 SelectedItems 属性更高效的修改选择的方法。The SelectAll, SelectRange, and DeselectRange methods provide a more efficient way to modify the selection than using the SelectedItems property. 这些方法使用项目索引范围进行选择或取消选择。These methods select or deselect using ranges of item indexes. 虚拟化的项目将保持虚拟化状态,因为仅使用了索引。Items that are virtualized remain virtualized, because only the index is used. 指定范围中的所有项目均已选定(或已取消选定),无论初始选择状态是什么。All items in the specified range are selected (or deselected), regardless of their original selection state. SelectionChanged 事件在每次调用这些方法时仅发生一次。The SelectionChanged event occurs only once for each call to these methods.

    重要

    仅当 SelectionMode 属性设置为 Multiple 或 Extended 时才应调用这些方法。You should call these methods only when the SelectionMode property is set to Multiple or Extended. 如果在 SelectionMode 是 Single 或 None 时调用 SelectRange,将引发异常。If you call SelectRange when the SelectionMode is Single or None, an exception is thrown.

    当使用索引范围选择项目时,请使用 SelectedRanges 属性获取列表中的所有选定范围。When you select items using index ranges, use the SelectedRanges property to get all selected ranges in the list.

    如果 ItemsSource 实现了 IItemsRangeInfo,并且你使用这些方法修改选择,则“AddedItems”和“RemovedItems”属性将不会在 SelectionChangedEventArgs 中进行设置 。If the ItemsSource implements IItemsRangeInfo, and you use these methods to modify the selection, the AddedItems and RemovedItems properties are not set in the SelectionChangedEventArgs. 设置这些属性需要对项目对象执行取消虚拟化操作。Setting these properties requires de-virtualizing the item object. 改为使用 SelectedRanges 属性获取项目。Use the SelectedRanges property to get the items instead.

    通过调用 SelectAll 方法,可以选择集合中的所有项目。You can select all items in a collection by calling the SelectAll method. 但是没有相应的方法来取消选择所有项目。However, there is no corresponding method to deselect all items. 你可以通过以下方法取消选择所有项目:调用 DeselectRange,并传递 FirstIndex 值为 0 并且 Length 值等于集合中项目数的 ItemIndexRangeYou can deselect all items by calling DeselectRange and passing an ItemIndexRange with a FirstIndex value of 0 and a Length value equal to the number of items in the collection. 下面的示例将显示此内容以及用于选择所有项的选项。This is shown in the example below, along with an option to select all items.

    XAMLXAML

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

    C#C#

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

    有关如何更改所选项目外观的信息,请参阅项目容器和模板For info about how to change the look of selected items, see Item containers and templates.

    拖放Drag and drop

    ListView 和 GridView 控件支持在其自身内部以及它们自身与其他 ListView 和 GridView 控件之间拖放项目。ListView and GridView controls support drag and drop of items within themselves, and between themselves and other ListView and GridView controls. 有关实现拖放模式的详细信息,请参阅拖放For more info about implementing the drag and drop pattern, see Drag and drop.

    获取示例代码Get the sample code