项目视图
使用项目视图可显示数据项目的集合,例如相册中的照片或产品目录中的项目。
项目视图类似于列表视图控件和网格视图控件,在使用这些控件的大多数情况下都会使用项目视图。 项目视图的一个优点是能够在保留项目选择的同时动态切换布局。
项目视图控件是使用 ItemsRepeater、ScrollView、ItemContainer 和 ItemCollectionTransitionProvider 组件生成的,因此它提供了插入自定义 Layout 或 ItemCollectionTransitionProvider 实现的独特功能。 项目视图的内部 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 在 ResourceDictionary 中Page.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 提供各种属性来控制:
- 布局是垂直还是水平 (Orientation)
- 项目间距 (Spacing)
可以将布局与 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 提供各种属性来控制:
- 项目的大小和间距(LineHeight、LineSpacing、MinItemSpacing)
- 项目的排列(ItemsJustification、ItemsStretch)
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 提供各种属性来控制:
- 布局是基于行还是列 (Orientation)
- 行数或列数 (MaximumRowsOrColumns)
- 项目的大小和间距(MinItemHeight、MinItemWidth、MinColumnSpacing、MinRowSpacing)
- 项目的排列(ItemsJustification、ItemsStretch)
提示
使用 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 也设置为 Single
、Multiple
或 Extended
。 如果执行此操作,则首先引发 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 |
Multiple
选择的默认选择指示如下所示。
扩展选择
下表介绍在 SelectionMode 设置为 Extended
时,键盘、鼠标和触摸的交互情况。
修改键 | 交互 |
---|---|
无 | Single 选择相同。 |
Ctrl | |
Shift |
当 SelectionMode 设置为 Multiple
或 Extended
时,可以从 SelectedItems 属性获取选定的数据项目。
SelectedItem 和 SelectedItems 属性已同步。 例如,如果将 SelectedItem 设置为 null
,则 SelectedItems 为空。 在多选模式下,SelectedItem 包含首先选择的项目。
Extended
选择的默认选择指示与 Single
选择相同,如下所示。
通过编程方式管理项目选择
注意
这些选择方法忽略了 SelectionMode 属性,即使在 SelectionMode 为 Single
或 None
时也有效。
有时,可能需要通过编程方式操作 ItemsView 项目选择。 例如,你可能会显示“全选”按钮,让用户选择列表中的所有项目。 在这种情况下,从 SelectedItems 集合逐个添加或删除项目通常效率不高。 使用 Select、SelectAll、Deselect 和 InvertSelection 方法修改选择比使用 SelectedItems 属性更有效。
提示
通过调用 SelectAll 方法,可以选择集合中的所有项目。 没有相应的方法来取消选择所有项目。 但是,可以通过调用 SelectAll,然后立即调用 InvertSelection 来取消选择所有项目。
获取示例代码
- WinUI 库示例 - 以交互式格式查看所有 XAML 控件。