
你可以在 XAML 中使用 ListView 或 GridView 控件来显示数据集合,如联系信息列表、库中的图像或电子邮件收件箱中的内容。
目标: 了解如何将 ListView 和 GridView 控件添加到 Windows 应用商店应用。
先决条件
我们假定你可以向使用 C++、C# 或 Visual Basic 的基本 Windows 运行时应用中添加控件。有关添加控件的说明,请参阅快速入门:添加控件和处理事件。
说明
1. 选择 ListView 或 GridView
ListView 和 GridView 控件均用于显示应用中数据的集合。它们的功能十分相似,但是显示数据的方式不同。它们都派生自 ItemsControl 类。涉及到ItemsControl 时,信息会同时应用到 ListView 和 GridView 控件。
ListView 采用垂直堆叠的方式显示数据。该控件常用于显示按顺序排列的项目列表,如电子邮件列表或搜索结果列表。它在主从式列表情况下也很有用,其中的列表项仅包含少量信息,并且选定项目的详细信息会单独显示。
GridView 采用水平堆叠的方式显示数据。对于占驻较多控件的每个项目(如照片库),当你需要为其显示丰富的视觉信息时,该控件很常用。
你可以通过将项直接添加到其 Items 集合或将其 ItemsSource 属性绑定到数据源来填充 ItemsControl。同时将 ListView 和 GridView 绑定到同一数据源的情况很常见。你可以显示其中一个并将另一个隐藏起来,从而将 UI 调整为摆脱那个的方向和分辨率。
下面的 ListView 显示了当靠近另一个应用时变窄的应用中的项目,GridView 显示了当该应用全屏显示时的同一组项目。

2. 将项添加到项集合
可以通过使用 Extensible Application Markup Language (XAML) 或代码向 Items 集合添加项。在以下情况下通常采用这种方式添加项:具有不更改且使用 XAML 轻松定义的少量项,或者在运行时采用代码生成项。以下是带有使用 XAML 内联定义项的 ListView 和带有使用代码添加项的 GridView。
<ListView x:Name="listView1" SelectionChanged="ListView_SelectionChanged">
<x:String>Item 1</x:String>
<x:String>Item 2</x:String>
</ListView>
// Create a new grid view, add content,
// and add a SelectionChanged event handler.
GridView gridView1 = new GridView();
gridView1.Items.Add("Item 1");
gridView1.Items.Add("Item 2");
gridView1.SelectionChanged += GridView_SelectionChanged;
// Add the grid view to a parent container in the visual tree.
stackPanel1.Children.Add(gridView1);
向 ItemsControl 添加项时,这些项目会自动放置在项容器中。用于 ListView 的项容器为 ListViewItem,用于GridView 的项容器为 GridViewItem。要更改项如何显示,你可通过设置 ItemContainerStyle 属性应用样式到该项容器。
使用 XAML 定义项时,这些项还会自动添加到 Items 集合。
3. 设置项目源
大部分应用使用 ListView 或 GridView 显示源(例如数据库或 Internet)中的数据。若要填充数据源中的ItemsControl,请将其 ItemsSource 属性设置为数据项集合。
以下是一些支持绑定到 ItemsControl 的常见集合类型。
| 集合类型 | 使用时间 |
|---|---|
| List(Of T) | 当集合在运行时不更改时。列表或网格的内容在其创建后为静态。 |
| ObservableCollection(Of T) | 当集合在运行时更改时。系统会向列表或网格通知对集合的更改,然后列表或网格会更新显示。 |
| FileInformationFactory.GetVirtualizedFilesVector | 绑定到文件集合。 |
| FileInformationFactory.GetVirtualizedFoldersVector | 绑定到文件夹集合。 |
| FileInformationFactory.GetVirtualizedItemsVector | 绑定到存储项集合。 |
此时,直接在代码中将 ItemsSource 设置为集合实例。
// Data source.
List<String> itemsList = new List<string>();
itemsList.Add("Item 1");
itemsList.Add("Item 2");
// Create a new grid view, add content,
// and add a SelectionChanged event handler.
GridView gridView1 = new GridView();
gridView1.ItemsSource = itemsList;
gridView1.SelectionChanged += GridView_SelectionChanged;
// Add the grid view to a parent container in the visual tree.
stackPanel1.Children.Add(gridView1);
还可以将 ItemsSource 属性绑定到 CollectionViewSource。CollectionViewSource 充当集合类的代理角色,以启用货币和分组支持。如果将相同数据同时绑定到 ListView 和 GridView 来支持在较窄视图和较宽视图之间切换,则应绑定到CollectionViewSource 以便两个视图都有相同的当前项。有关详细信息,请参阅使用 XAML 进行数据绑定。
若要在列表或网格中显示分组项,则数据源必须支持分组功能,必须将 ItemsSource 绑定到 CollectionViewSource,并且将其 IsSourceGrouped 属性设置为 True。有关详细信息,请参阅如何对数据控件中的项进行分组。
在下面的代码中,ItemsSource 绑定到名为 itemsViewSource 的 CollectionViewSource。若要查看此示例和以下示例的完整代码,请使用 Microsoft Visual Studio 中的“拆分应用程序”模板创建应用。
<Page.Resources>
<!-- Collection of items displayed by this page -->
<CollectionViewSource x:Name="itemsViewSource" Source="{Binding Items}"/>
</Page.Resources>
<ListView x:Name="itemListView"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}"/>
4. 指定项目的外观
在默认情况下,数据项以绑定到的数据对象的字符串表现形式显示在列表或网格中。通过将 DisplayMemberPath 设置到特定的属性,你可以显示数据项的该属性的字符串表现形式。
一般来说,你会希望显示数据项的多个属性。若要具体地指定列表或网格中项的显示方式,则可以创建DataTemplate。DataTemplate 中的 XAML 定义用于显示各项的控件的布局。该布局中的控件可绑定到数据对象的属性,或者具有定义的嵌入内容。DataTemplate 会分配给 ListView 或 GridView 的 ItemTemplate 属性。
在本示例中,ListView 的 ItemTemplate 采用嵌入定义。下一示例显示 GridView,其 ItemTemplate 设置为名为Standard250x250ItemTemplate 的静态资源。
<ListView x:Name="itemListView"
Margin="120,0,0,60"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
SelectionChanged="ItemListView_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="110" Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="110" Height="110">
<Image Source="{Binding Image}" Stretch="UniformToFill"/>
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,0,0,0">
<TextBlock Text="{Binding Title}" Style="{StaticResource TitleTextStyle}" TextWrapping="NoWrap"/>
<TextBlock Text="{Binding Subtitle}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap"/>
<TextBlock Text="{Binding Description}" Style="{StaticResource BodyTextStyle}" MaxHeight="60"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
以下是数据模板所定义布局的外观。

5. 指定视图布局
若要指定如何在列表或网格视图中摆放项,则可以设置 ItemsPanel 属性来指定设置为布局 Panel 的ItemsPanelTemplate。默认情况下,GridView 使用一个 WrapGrid 面板作为它的 ItemsPanel,ListView 使用一个VirtualizingStackPanel 作为它的 ItemsPanel。
下面介绍如何在 ListView 中使用 WrapGrid 更改项目的布局。WrapGrid 替换默认的 VirtualizingStackPanel,它将项目排成一列。我们设置 WrapGrid.MaximumRowsOrColumns 属性,以便将项目排成两列。
<ListView Height="320" Width="260">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Horizontal" MaximumRowsOrColumns="2"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<Rectangle Height="100" Width="100" Fill="Blue" />
<Rectangle Height="100" Width="100" Fill="Red" />
<Rectangle Height="100" Width="100" Fill="Yellow" />
<Rectangle Height="100" Width="100" Fill="Green" />
<Rectangle Height="100" Width="100" Fill="Gray" />
<Rectangle Height="100" Width="100" Fill="LightBlue" />
<Rectangle Height="100" Width="100" Fill="Pink" />
<Rectangle Height="100" Width="100" Fill="YellowGreen" />
</ListView>
下面是使用具有两列的 WrapGrid 作为它的 ItemsPanel的 ListView 外观。

6. 向视图中添加标题
你可以向 ListView 或 GridView 中添加标题,方法是为 Header 属性分配一个字符串或对象。可以通过设置HeaderTemplate 属性使用数据模板 定义 Header 的布局。
默认情况下,标题显示在视图的前沿。它显示在 ListView 的顶部,GridView 的左侧。如果 FlowDirection 属性设置为RightToLeft,则标题显示在 GridView 的右侧。
下面是标题中包含 StackPanel(具有文本和图像)的 GridView。此 XAML 是 Visual Studio“网格应用”模板的GroupDetail 页面中使用的 GridView 的简化版本。
<GridView x:Name="itemGridView"
Margin="0,-14,0,0"
Padding="120,0,120,50"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
ItemTemplate="{StaticResource Standard500x130ItemTemplate}">
<GridView.Header>
<StackPanel Width="480" Margin="0,4,14,0">
<TextBlock Text="{Binding Subtitle}" Margin="0,0,18,20"
Style="{StaticResource SubheaderTextStyle}" MaxHeight="60"/>
<Image Source="{Binding Image}" Height="400" Margin="0,0,18,20"
Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
<TextBlock Text="{Binding Description}" Margin="0,0,18,0"
Style="{StaticResource BodyTextStyle}"/>
</StackPanel>
</GridView.Header>
</GridView>
此处,GridView 的标题是轮廓为黄色的部分。

7. 设置视图的交互模式
在默认情况下,用户可在 ListView 或 GridView 中选择一个项目。要更改此行为,你可以将 SelectionMode 属性设置为 ListViewSelectionMode 枚举值,以允许多选或禁止选择。
下面是禁止选择的 ListView 和允许多选的 GridView 的代码。
<ListView x:Name="itemList"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
SelectionMode="None"/>
<GridView x:Name="itemGrid"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
SelectionChanged="ItemView_SelectionChanged"
SelectionMode="Extended"/>
若要响应列表或网格中的选择更改,请处理 SelectionChanged 事件。在事件处理程序代码中,可以从SelectionChangedEventArgs.AddedItems 属性获取选择项列表。在 SelectionChanged 事件之外,使用代码或通过数据绑定从 SelectedItem 和 SelectedItems 属性获取选择的项。
以下是上例中 GridView 的 SelectionChanged 事件处理程序。
List<object> selectedItems;
private void ItemView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// Use e.AddedItems to get the items that are selected in the ItemsControl.
selectedItems = (List<object>)e.AddedItems;
}
你还可以更改 ListView 或 GridView,从而使用户可以单击项目(如按钮),而不是选择项目。例如,当用户点击列表或网格中的一个项目时,如果你的应用导航至一个新页面,这将会很有用。要启用此行为,请将 SelectionMode 设置为None,将 IsItemClickEnabled 设置为 true,并对 ItemClick 事件进行处理,使其在用户点击项目时执行某些任务。
下面是具有可单击项的 GridView。ItemClick 处理程序中的代码会导航至一个新页面,并将点击的项目作为数据传递给新页面。
<GridView x:Name="itemGridView"
Margin="116,0,116,46"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
SelectionMode="None"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick"/>
private void ItemView_ItemClick(object sender, ItemClickEventArgs e)
{
// Navigate to the split page, configuring the new page
// by passing required information as a navigation parameter
this.Frame.Navigate(typeof(SplitPage), e.ClickedItem);
}
摘要和后续步骤
你了解了如何创建 ListView 和 GridView 控件来显示数据集合。
有关可以用在应用中的预定义项模板的列表,请参阅列表布局的项模板和网格布局的项模板。若要了解如何对项进行分组,请参阅如何对列表或网格中的项进行分组。
有关显示 ListView 和 GridView 控件的更多代码示例,请参阅以下示例:
- XAML ListView 和 GridView 基本示例
- XAML ListView 和 GridView 自定义交互示例
- XAML GridView 分组和 SemanticZoom 示例
- Visual Studio 中的“拆分应用”项目模板。