首页 > 代码库 > ListView 和 GridView

ListView 和 GridView

ListView 和 GridView ————转

1. 选择 ListView 或 GridView

ListViewGridView 控件均用于显示应用中数据的集合。它们的功能十分相似,但是显示数据的方式不同。它们都派生自 ItemsControl 类。

ListView 采用垂直堆叠的方式显示数据。该控件常用于显示按顺序排列的项目列表,如电子邮件列表或搜索结果列表。它在主从式列表情况下也很有用,其中的列表项仅包含少量信息,并且选定项目的详细信息会单独显示。

GridView 采用水平堆叠的方式显示数据。对于占驻较多控件的每个项目(如照片库),当你需要为其显示丰富的视觉信息时,该控件很常用。

你可以通过将项直接添加到其 Items 集合或将其 ItemsSource 属性绑定到数据源来填充 ItemsControl。同时将 ListViewGridView 绑定到同一数据源的情况很常见。你可以显示其中一个并将另一个隐藏起来,从而将 UI 调整为摆脱那个的方向和分辨率。

下面的 ListView 显示了贴靠应用中的项目,GridView 显示了当该应用全屏显示时的同一组项目。

ListView 和 GridView

2. 将项添加到项集合

可以通过使用可扩展应用程序标记语言 (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. 设置项目源

。如果 ItemsSource 属性已设置且使用 XAML 添加项,则会忽略该项。如果 ItemsSource 属性已设置且使用代码向 Items 集合中添加项,则会引发异常

以下是一些支持绑定到 ItemsControl 的常见集合类型。

集合类型 使用时间
List(Of T) 当集合在运行时不更改时。列表或网格的内容在其创建后为静态。
ObservableCollection(Of T) 当集合在运行时更改时。系统会向列表或网格通知对集合的更改,然后列表或网格会更新显示。
FileInformationFactory.GetVirtualizedFilesVector 绑定到文件集合。
FileInformationFactory.GetVirtualizedFoldersVector 绑定到文件夹集合。
FileInformationFactory.GetVirtualizedItemsVector 绑定到存储项集合。

此时,直接在代码中将 ItemsSource 设置为集合实例。

C#
C++
VB
复制
// 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 属性绑定到 CollectionViewSourceCollectionViewSource 充当集合类的代理角色,启用货币和分组支持。如果将相同数据同时绑定到 ListViewGridView 来支持在辅屏视图和全屏视图之间切换,则应绑定到 CollectionViewSource 以便两个视图都有相同的当前项。有关更多信息,请参阅使用 XAML 进行数据绑定。

若要在列表或网格中显示分组项,则数据源必须支持分组功能,必须将 ItemsSource 绑定到 CollectionViewSource,并且将其 IsSourceGrouped 属性设置为 True。有关详细信息,请参阅如何对数据控件中的项进行分组。

在下面的代码中,ItemsSource 绑定到名为 itemsViewSourceCollectionViewSource。若要查看此示例和以下示例的完整代码,请使用 Microsoft Visual Studio 2012 中的拆分应用程序模板创建应用。

<Page.Resources>
    <!-- Collection of items displayed by this page -->
    <CollectionViewSource x:Name="itemsViewSource" Source="{Binding Items}"/>
</Page.Resources>
XAML
<ListView x:Name="itemListView"     ItemsSource="{Binding Source={StaticResource itemsViewSource}}"/> 

4. 指定项目的外观

通过将 DisplayMemberPath 设置到特定的属性,设置itemTemplate

<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>
以下是数据模板所定义布局的外观。

ListView 数据模板

5. 指定视图布局

若要指定如何在列表或网格视图中摆放项,则可以设置 ItemsPanel 属性来指定设置为布局 PanelItemsPanelTemplate。默认情况下,GridView 使用一个 WrapGrid 面板作为它的 ItemsPanelListView 使用一个 VirtualizingStackPanel 作为它的 ItemsPanel

下面介绍如何在 ListView 中使用 WrapGrid 更改项目的布局。WrapGrid 替换默认的 VirtualizingStackPanel,它将项目排成一列。我们设置 WrapGrid.MaximumRowsOrColumns 属性,以便将项目排成两列。

XAML
复制
<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 作为它的 ItemsPanelListView 外观。

具有两列的 ListView

6. 向视图中添加标题

你可以向 ListViewGridView 中添加标题,方法是为 Header 属性分配一个字符串或对象。可以通过设置 HeaderTemplate 属性使用数据模板 定义 Header 的布局。

默认情况下,标题显示在视图的前沿。它显示在 ListView 的顶部,GridView 的左侧。如果 FlowDirection 属性设置为 RightToLeft,则标题显示在 GridView 的右侧。

下面是标题包含 StackPanel(具有文本和图像)的 GridView。此可扩展应用程序标记语言 (XAML) 是 Microsoft Visual Studio“网格应用”模板的 GroupDetail 页面中使用的 GridView 的简化版本。

XAML
复制
<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 的标题是轮廓为黄色的部分。

ListView 数据模板

7. 设置视图的交互模式

在默认情况下,用户可在 ListViewGridView 中选择一个项目。要更改此行为,你可以将 SelectionMode 属性设置为 ListViewSelectionMode 枚举值,以允许多选或禁止选择。

下面是禁止选择的 ListView 和允许多选的 GridView 的代码。

XAML
复制
<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 事件之外,使用代码或通过数据绑定从 SelectedItemSelectedItems 属性获取选择的项。

以下是上例中 GridView 的 SelectionChanged 事件处理程序。

C#
复制
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;
}你还可以更改 ListViewGridView,从而使用户可以单击项目(如按钮),而不是选择项目。例如,当用户点击列表或网格中的一个项目时,如果你的应用导航至一个新页面,这将会很有用。要启用此行为,请将 SelectionMode 设置为 None,将 IsItemClickEnabled 设置为 true,并对 ItemClick 事件进行处理,使其在用户点击项目时执行某些任务。

下面是具有可单击项的 GridViewItemClick 处理程序中的代码会导航至一个新页面,并将点击的项目作为数据传递给新页面。

XAML
复制
<GridView x:Name="itemGridView"
          Margin="116,0,116,46"
          ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
          ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
          SelectionMode="None"
          IsItemClickEnabled="True"
          ItemClick="ItemView_ItemClick"/>
C#
复制
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);
}