SuperAPI AI 工具集

maui-collectionview

编程与开发

查看项目

更新于 10-16 03:01

技能介绍

用途

CollectionView 是 .NET MAUI 中用于显示可滚动列表和网格数据的主要控件。它取代 ListView,具备更好的性能、灵活的布局,且无需 ViewCell。本技能指南用于在 .NET MAUI 应用中实现 CollectionView,涵盖数据展示、布局(列表与网格)、选择、分组、滚动、空视图、模板等内容。

适用场景

  • 显示可滚动的数据项列表或网格
  • 将对象集合绑定到模板化项布局
  • 添加选择(单选或多选)、分组或下拉刷新
  • 实现无限滚动/增量加载
  • 在列表项上显示滑动操作
  • 无数据时显示空状态

不适用场景

  • 固定数量项的静态布局——直接使用 Grid 或 StackLayout
  • 地图图钉列表——使用 Microsoft.Maui.Controls.Maps NuGet 包
  • 基于表格的数据录入表单——使用标准表单控件
  • 无交互的纯文本列表——考虑在 StackLayout 上使用 BindableLayout

主要能力

基本设置

将 ItemsSource 绑定到 ObservableCollection<T>,以便添加/移除时更新 UI;每个项模板根必须是 Layout 或 View,绝不要使用 ViewCell;始终为 DataTemplate 设置 x:DataType 以启用编译绑定。

布局

通过 ItemsLayout 控制排列,默认是 VerticalList。可选:VerticalList(默认)、HorizontalList、GridItemsLayout 配合 Orientation="Vertical"(垂直网格)、GridItemsLayout 配合 Orientation="Horizontal"(水平网格)。网格布局可设置 Span、VerticalItemSpacing、HorizontalItemSpacing。

选择

  • None:无绑定
  • Single:绑定 SelectedItem,TwoWay
  • Multiple:绑定 SelectedItems(类型 IList<object>),OneWay

可用 VisualStateManager 通过 Normal 与 Selected 视觉状态高亮选中项。

分组

创建继承自 List<T> 的分组类,绑定到 ObservableCollection<AnimalGroup> 并设置 IsGrouped="True",通过 GroupHeaderTemplate 定义组头。

下拉刷新

将 CollectionView 包裹在 RefreshView 中,完成后将 IsRefreshing 设回 false。

增量加载(无限滚动)

设置 RemainingItemsThreshold 与 RemainingItemsThresholdReachedCommand。注意:不要与非虚拟化布局一起使用。LinearItemsLayout 和 GridItemsLayout 支持虚拟化;在 StackLayout 上使用 BindableLayout 没有虚拟化,会持续触发阈值事件。

SwipeView

DataTemplate 内的命令无法直接访问 ViewModel,需使用 RelativeSource AncestorType。

EmptyView

当 ItemsSource 为空或 null 时显示。可传简单字符串或自定义 ContentView。

页眉与页脚

使用 CollectionView.Header / Footer;数据绑定时使用 HeaderTemplate / FooterTemplate。

滚动

通过 ScrollTo 按索引或项进行编程滚动,position 可选 ScrollToPosition.MakeVisible、Start、Center、End。

Snap Points

SnapPointsType:None、Mandatory、MandatorySingle;SnapPointsAlignment:Start、Center、End。

从 ListView 迁移

ListView 仍可编译,但从 .NET 10 起被标记为 [Obsolete]("ListView is deprecated. Please use CollectionView instead.")。在 .NET 9 及更早版本中未废弃,需先检查项目目标框架。CollectionView 更快、无需 ViewCell、支持灵活布局。迁移对照:ViewCell 模板根 → 任何 View/Layout 根;ItemSelected 事件 → SelectionChanged 事件或 SelectionChangedCommand;ItemTapped 事件 → 项模板中的 TapGestureRecognizer;IsPullToRefreshEnabled + Refreshing → 包裹在 RefreshView 中;IsGroupingEnabled → IsGrouped;HasUnevenRows="True" → 默认 ItemSizingStrategy="MeasureAllItems";RowHeight → 在项模板中设置高度;SeparatorVisibility/SeparatorColor → 无等效项,在项模板中绘制 BoxView/Border。

性能提示

仅在用户报告性能问题或明确询问性能时应用。使用 MeasureFirstItem 处理统一项尺寸,比默认 MeasureAllItems 快得多。在 CollectionView 本身(StructuredItemsView 上声明)设置,而非 LinearItemsLayout / GridItemsLayout。以下情况保持默认 MeasureAllItems:项高度不一、DataTemplateSelector 返回不同模板、首项不典型、项尺寸依赖尚未加载的运行时数据。

列表在首次渲染后变更时使用 ObservableCollection<T>(实现 INotifyCollectionChanged,就地 Add/Remove/Insert 增量更新 UI)。若列表绑定后不再变化,List<T> 也可。替换 ItemsSource 无论集合类型都会重新渲染全部,因此应就地修改绑定集合而非重新赋值。在 UI 线程更新集合:MainThread.BeginInvokeOnMainThread(() => Items.Add(item))。

常见陷阱

  • 项变更时 UI 不更新:使用 ObservableCollection<T>,而非 List<T>
  • 应用崩溃或空白项:绝不使用 ViewCell,使用 Grid、StackLayout 或任何 View 作为模板根
  • 项消失或布局损坏:始终在 UI 线程更新 ItemsSource 和集合
  • 增量加载无限触发:不要用 StackLayout 作为布局

限制

本指南为参考资料而非清单,大多数请求只需其中一两个部分。以下情况不应采取行动:用户提出的是狭窄问题,只回答该问题;用户现有代码已可工作,不要重写;改动仅为风格性;控件不是 CollectionView;问题实际是绑定、依赖注入或导航问题,应转交相应技能。