项目视图

使用项目视图可显示数据项目的集合,例如相册中的照片或产品目录中的项目。

项目视图类似于列表视图控件和网格视图控件,在使用这些控件的大多数情况下都会使用项目视图。 项目视图的一个优点是能够在保留项目选择的同时动态切换布局。

项目视图控件是使用 ItemsRepeaterScrollViewItemContainerItemCollectionTransitionProvider 组件生成的,因此它提供了插入自定义 LayoutItemCollectionTransitionProvider 实现的独特功能。 项目视图的内部 ScrollView 控件允许滚动和缩放项目。 它还提供了列表视图和网格视图使用的 ScrollViewer 控件中未提供的功能,例如在编程滚动期间控制动画这项功能。

与列表视图和网格视图控件一样,项目视图可以使用 UI 和数据虚拟化;处理键盘、鼠标、手写笔和触控输入;并提供内置的辅助功能支持。

这是正确的控件吗?

使用项目视图可执行以下操作:

  • 显示一个集合,其中所有项目都应具有相同的视觉对象和交互行为。
  • 显示一个内容集合,并能够在列表、网格和自定义布局之间进行切换。
  • 囊括各种用例,包括以下常见用例:
    • 店面类型的用户界面(例如,浏览应用、歌曲、产品)
    • 交互式照片库
    • 联系人列表

创建项目视图

WinUI 3 库应用包括大多数 WinUI 3 控件、特性和功能的交互式示例。 通过 Microsoft Store 获取应用,或在 GitHub 上获取源代码

ItemsView 可以显示任何类型的项目集合。 若要填充视图,请将 ItemsSource 属性设置为数据源。

注意

与其他集合控件(派生自 ItemsControl 的控件)不同,ItemsView 没有可直接添加数据项目的 Items 属性。

设置项目源

通常使用项目视图显示源(例如数据库或 Internet)中的数据。 若要填充数据源中的项目视图,请将其 ItemsSource 属性设置为数据项目集合。

使用代码设置 ItemsSource

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

 // Data source.
 List<String> itemsList = new List<string>();
 itemsList.Add("Item 1");
 itemsList.Add("Item 2");

 // Create a new ItemsView and set the data source.
 ItemsView itemsView1 = new ItemsView();
 itemsView1.ItemsSource = itemsList;

 // Add the ItemsView to a parent container in the visual tree.
 rootGrid.Children.Add(itemsView1);

使用 XAML 绑定 ItemsSource

还可以将 ItemsSource 属性绑定到 XAML 中的集合。 有关详细信息,请参阅使用 XAML 进行数据绑定

重要

在 DataTemplate 中使用 x:Bind 标记扩展时,必须指定数据模板中的数据类型 (x:DataType)。

在这里,ItemsSource 会绑定到自定义数据对象的集合(Photo 类型)。

<ItemsView ItemsSource="{x:Bind Photos}">

</ItemsView>
public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
        Photos = new ObservableCollection<Photo>();
        PopulatePhotos();
    }

    public ObservableCollection<Photo> Photos
    {
        get; private set;
    }


    private void PopulatePhotos()
    {
        // Populate the Photos collection. 
    }
}

public class Photo
{
    public BitmapImage PhotoBitmapImage { get; set; }
    public string Title { get; set; }
    public int Likes { get; set; }
}

指定项目的外观

在默认情况下,数据项目以绑定到的数据对象的字符串表现形式显示在项目视图中。 你通常希望更丰富地呈现你的数据。 若要具体地指定项目视图中项目的显示方式,可以创建 DataTemplate。 DataTemplate 中的 XAML 定义用于显示各项的控件的布局和外观。 该布局中的控件可绑定到数据对象的属性,或者具有在内联中定义的静态内容。 将 DataTemplate 分配给 ItemsView 控件的 ItemTemplate 属性。

重要

DataTemplate 的根元素必须是 ItemContainer;否则将引发异常。 ItemContainer 是一个独立的基元控件,由 ItemsView 用来显示项目集合中单个项目的选择状态和其他可视化效果。

在此示例中,DataTemplate 在 ResourceDictionaryPage.Resources定义。 它有一个 Image 控件,用于显示图片以及一个包含图像标题和接收的赞数的覆盖层。

 <Page.Resources>
     <DataTemplate x:Key="PhotoItemTemplate" x:DataType="local:Photo">
         <ItemContainer AutomationProperties.Name="{x:Bind Title}">
             <Grid>
                 <Image Source="{x:Bind PhotoBitmapImage, Mode=OneWay}" 
                        Stretch="UniformToFill" MinWidth="70"
                        HorizontalAlignment="Center" VerticalAlignment="Center"/>
                 <StackPanel Orientation="Vertical" Height="40" Opacity=".75"
                             VerticalAlignment="Bottom" Padding="5,1,5,1" 
                             Background="{ThemeResource SystemControlBackgroundBaseMediumBrush}">
                     <TextBlock Text="{x:Bind Title}" 
                                Foreground="{ThemeResource SystemControlForegroundAltHighBrush}"/>
                     <StackPanel Orientation="Horizontal">
                         <TextBlock Text="{x:Bind Likes}"
                                    Style="{ThemeResource CaptionTextBlockStyle}"
                                    Foreground="{ThemeResource SystemControlForegroundAltHighBrush}"/>
                         <TextBlock Text=" Likes"
                                    Style="{ThemeResource CaptionTextBlockStyle}"
                                    Foreground="{ThemeResource SystemControlForegroundAltHighBrush}"/>
                     </StackPanel>
                 </StackPanel>
             </Grid>
         </ItemContainer>
     </DataTemplate>
 </Page.Resources>

 <Grid x:Name="rootGrid">
     <ItemsView ItemsSource="{x:Bind Photos}" Width="480" Height="400" 
                ItemTemplate="{StaticResource PhotoItemTemplate}">
     </ItemsView>
 </Grid>

下面展示了数据模板定义的项目布局。

包含图像标题和接收赞数的覆盖的自行车照片。

更改项的布局

将项目添加到 ItemsView 控件时,该控件会在 ItemContainer 中自动将每个项目换行,然后布局所有项目容器。 这些项目容器的布局方式取决于控件的 Layout 属性。

可以通过调整当前布局上的属性来修改项目的布局,也可以完全将当前布局替换为其他布局。 可以使用下一步所述的布局之一,也可以从 Layout 类派生自定义布局。

StackLayout

默认情况下,ItemsView 使用 StackLayout,它会使用默认属性设置和简单的图像模板生成如下所示的垂直列表。

垂直列表中显示的照片集合。

此 XAML 在 StackLayout 中将项目之间的间距设置为 5px。

<ItemsView ItemsSource="{x:Bind Photos}" Width="480" Height="400" 
           ItemTemplate="{StaticResource PhotoItemTemplate}">
    <ItemsView.Layout>
        <StackLayout Spacing="5"/>
    </ItemsView.Layout>
</ItemsView>

StackLayout 提供各种属性来控制:

可以将布局与 ItemTemplate 结合使用,为集合提供各种外观以满足你的需求。 例如,WinUI 库示例将配合 StackLayout 使用的 ItemTemplate 更改为如下所示。

垂直列表中显示的小型照片集合,每个照片下方有几行文本。

LinedFlowLayout

LinedFlowLayout 以换行布局按从左到右,然后从上到下的顺序放置元素。 使用此布局可显示项目集合,其中项目的高度固定,但宽度可变。 建议将其用于基于图像的集合。 此布局还具有内置动画,这些动画在集合添加或删除项目以及调整视图大小时播放。

下面是以横格流布局显示照片集合的项目视图。

<ItemsView Width="500" Height="400" HorizontalAlignment="Left"
           ItemTemplate="{StaticResource LinedFlowLayoutItemTemplate}">
    <ItemsView.Layout>
        <LinedFlowLayout ItemsStretch="Fill" 
                         LineHeight="160" 
                         LineSpacing="5"
                         MinItemSpacing="5"/>
    </ItemsView.Layout>
</ItemsView>

线条流布局中显示的照片集合,其中每个项目的高度相同,但宽度因照片纵横比的原始大小而异。

LinedFlowLayout 提供各种属性来控制:

UniformGridLayout

UniformGridLayout 以换行布局按从左到右或从上到下的顺序(具体取决 Orientation)放置元素。 每个项目的大小相同。

下面是以统一网格布局显示照片集合的项目视图。

<ItemsView ItemsSource="{x:Bind Photos}" Width="480" Height="400"
           ItemTemplate="{StaticResource PhotoItemTemplate}">
    <ItemsView.Layout>
        <UniformGridLayout MaximumRowsOrColumns="3" 
                           MinRowSpacing="5" 
                           MinColumnSpacing="5"/>
    </ItemsView.Layout>
</ItemsView>

统一网格布局中显示的照片集合,其中每个项目的大小都相同。

UniformGridLayout 提供各种属性来控制:

提示

使用 WinUI 3 库应用中的互动演示实时查看这些属性的效果。

项目选择和交互

可以从多种方式中进行选择,让用户与项目视图进行交互。 默认情况下,用户可以选择单个项目。 你可以更改 SelectionMode 属性以启用多选或禁用选择。 可以设置 IsItemInvokedEnabled 属性,以便用户单击某个项目来调用操作,而不是选择该项目。

此表显示用户可与列表视图交互的方式以及你响应交互的方式。

若要启用此交互: 使用这些设置: 处理此事件: 使用此属性以获取选定的项目:
无交互 SelectionMode="None"
IsItemInvokedEnabled="False"
空值 空值
单选 SelectionMode="Single"
IsItemInvokedEnabled="False"
SelectionChanged SelectedItem
多重选择 SelectionMode="Multiple"
IsItemInvokedEnabled="False"
SelectionChanged SelectedItems
扩展选择 SelectionMode="Extended"
IsItemInvokedEnabled="False"
SelectionChanged SelectedItems
单击 SelectionMode="None"
IsItemInvokedEnabled="True"
ItemInvoked 不可用

注意

可以启用 IsItemInvokedEnabled 来引发 ItemInvoked 事件,同时 SelectionMode 也设置为 SingleMultipleExtended。 如果执行此操作,则首先引发 ItemInvoked 事件,然后引发 SelectionChanged 事件。 在某些情况下(例如,如果转到 ItemInvoked 事件处理程序中的另一页),则不引发 SelectionChanged 事件,并且不选择该项目。

可以使用 XAML 或代码设置这些属性,如下所示:

<ItemsView x:Name="myItemsView" SelectionMode="None" IsItemInvokedEnabled="True"/>
myItemsView.SelectionMode = ItemsViewSelectionMode.None;
myItemsView.IsItemInvokedEnabled = true;

只读

可以将 SelectionMode 属性设置为 ItemsViewSelectionMode.None 以禁用项目选择。 这会将控件置于只读模式下,使其用于显示数据,但不是为了与数据交互。 也就是说,虽然已禁用项目选择,但未禁用控件本身。

注意

仍然可以通过编程方式选择和取消选择项目,但不能通过用户交互进行选择和取消选择。

单选

下表介绍在 SelectionMode 设置为 Single 时,键盘、鼠标和触摸的交互情况。

修改键 交互
  • 用户可以使用空格键、鼠标单击或点击来选择单个项目。
  • Ctrl
  • 用户可以使用空格键、鼠标单击或点击来取消选择单个项目。
  • 通过使用箭头键,用户可以移动焦点,且不会影响选择。
  • 当 SelectionMode 设置为 Single 时,可以从 SelectedItem 属性获取选定的数据项目。 如果未选择任何项目,SelectedItem 为 null

    如果你尝试像 SelectedItem 那样设置不在项目集合中的项目,则该操作将被忽略,并且 SelectedItem 为 null

    Single 选择的默认选择指示如下所示。

    项目视图中具有蓝色边框的图像,指示未选择的图像旁边没有边框的选择。

    多重选择

    下表介绍在 SelectionMode 设置为 Multiple 时,键盘、鼠标和触摸的交互情况。

    修改键 交互
  • 用户可以使用空格键、鼠标单击或点击选择焦点项目来选择多个项目。
  • 通过使用箭头键,用户可以移动焦点,且不会影响选择。
  • Shift
  • 用户可以在选择中通过先后单击或点击第一个和最后一个项目来选择多个连续项目。
  • 通过使用箭头键,用户可以从按 Shift 键时选择的项目开始,选择连续项目。
  • Multiple 选择的默认选择指示如下所示。

    项目视图中有蓝色边框的图像,并覆盖了一个选中的复选框,用于指示未选中的图像旁边没有边框和未选中复选框的选定内容。

    扩展选择

    下表介绍在 SelectionMode 设置为 Extended 时,键盘、鼠标和触摸的交互情况。

    修改键 交互
  • 该行为与 Single 选择相同。
  • Ctrl
  • 用户可以使用空格键、鼠标单击或点击选择焦点项目来选择多个项目。
  • 通过使用箭头键,用户可以移动焦点,且不会影响选择。
  • Shift
  • 用户可以在选择中通过先后单击或点击第一个和最后一个项目来选择多个连续项目。
  • 通过使用箭头键,用户可以从按 Shift 键时选择的项目开始,选择连续项目。
  • 当 SelectionMode 设置为 MultipleExtended 时,可以从 SelectedItems 属性获取选定的数据项目。

    SelectedItem 和 SelectedItems 属性已同步。 例如,如果将 SelectedItem 设置为 null,则 SelectedItems 为空。 在多选模式下,SelectedItem 包含首先选择的项目。

    Extended 选择的默认选择指示与 Single 选择相同,如下所示。

    项视图中的两个图像,每个图像周围带有蓝色边框以指示所选内容。

    通过编程方式管理项目选择

    注意

    这些选择方法忽略了 SelectionMode 属性,即使在 SelectionMode 为 SingleNone 时也有效。

    有时,可能需要通过编程方式操作 ItemsView 项目选择。 例如,你可能会显示“全选”按钮,让用户选择列表中的所有项目。 在这种情况下,从 SelectedItems 集合逐个添加或删除项目通常效率不高。 使用 SelectSelectAllDeselectInvertSelection 方法修改选择比使用 SelectedItems 属性更有效。

    提示

    通过调用 SelectAll 方法,可以选择集合中的所有项目。 没有相应的方法来取消选择所有项目。 但是,可以通过调用 SelectAll,然后立即调用 InvertSelection 来取消选择所有项目。

    获取示例代码