关于 maui-collectionview
面向 .NET MAUI 的 CollectionView 技能,介绍如何展示可滚动的数据列表和网格。内容涵盖绑定、刷新和增量加载,并说明避免常见界面问题及性能问题的布局与线程做法。
主要功能
- 01使用 ObservableCollection 绑定数据
- 02配置不含 ViewCell 的项目模板
- 03通过祖先绑定使用 SwipeView
- 04添加下拉刷新和增量加载
- 05选择支持虚拟化的布局
- 06优化尺寸测量与 UI 线程更新
适用场景
- 01创建可滚动且数据会变化的列表或网格
- 02添加滑动命令和下拉刷新
- 03滚动列表时加载更多项目
- 04排查空白项目或滚动缓慢问题
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ davidortinau/ maui-skills --skill maui-collectionview安装后在 Claude Code 中输入/maui-collectionview确认已加载。
附带文件evals/evals.jsonreferences/collectionview-api.md
详细介绍
CollectionView – .NET MAUI
使用 CollectionView 显示可滚动的数据列表和网格。
它取代了 ListView,性能更好、布局更灵活,而且不需要 ViewCell。
基本模式
基本设置
<CollectionView ItemsSource="{Binding Items}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:Item">
<HorizontalStackLayout Padding="8" Spacing="8">
<Image Source="{Binding Icon}" WidthRequest="40" HeightRequest="40" />
<Label Text="{Binding Name}" VerticalOptions="Center" />
</HorizontalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
- 将
ItemsSource绑定到ObservableCollection<T>,以便在添加或移除项目时更新 UI。 - 每个项目模板的根元素必须是
Layout或View——切勿使用ViewCell。 - 始终在
DataTemplate上设置x:DataType,以使用编译绑定。
SwipeView——从 DataTemplate 内部进行绑定
DataTemplate 内的命令无法直接访问 ViewModel。请使用 RelativeSource AncestorType:
<SwipeItem Text="Delete"
BackgroundColor="Red"
Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodels:MainViewModel}}, Path=DeleteCommand}"
CommandParameter="{Binding}" />
下拉刷新
将 CollectionView 包装在 RefreshView 中。完成后将 IsRefreshing 设回 false:
<RefreshView IsRefreshing="{Binding IsRefreshing}"
Command="{Binding RefreshCommand}">
<CollectionView ItemsSource="{Binding Items}" />
</RefreshView>
增量加载(无限滚动)
<CollectionView ItemsSource="{Binding Items}"
RemainingItemsThreshold="5"
RemainingItemsThresholdReachedCommand="{Binding LoadMoreCommand}" />
⚠️ 切勿与基于 StackLayout 的 ItemsLayout 搭配使用——它没有虚拟化功能,会不断触发达到阈值事件。请始终使用
LinearItemsLayout或GridItemsLayout。
性能提示
- 对于大小一致的项目,使用
MeasureFirstItem——它比默认的MeasureAllItems快很多:<LinearItemsLayout Orientation="Vertical" ItemSizingStrategy="MeasureFirstItem" /> - 始终使用
ObservableCollection<T>,不要使用List<T>。替换List会导致完整重新渲染。 - 在 UI 线程上更新集合——
MainThread.BeginInvokeOnMainThread(() => Items.Add(item))。
常见问题
| 问题 | 解决方法 |
|---|---|
| 项目变化时 UI 不更新 | 使用 ObservableCollection<T>,不要使用 List<T>。 |
| 应用崩溃或项目空白 | 切勿使用 ViewCell——使用 Grid、StackLayout 或任何 View 作为模板根元素。 |
| 项目消失或布局错乱 | 始终在 UI 线程上更新 ItemsSource 和集合(MainThread.BeginInvokeOnMainThread)。 |
| 增量加载不断触发 | 不要将 StackLayout 用作布局;请使用 LinearItemsLayout 或 GridItemsLayout。 |
| EmptyView 显示不正确 | 将自定义空视图包装在 ContentView 中。 |
| 滚动性能不佳 | 对大小一致的项目使用 MeasureFirstItem 尺寸策略。 |
| 选中状态不可见 | 在项目模板的根元素中添加 VisualState Name="Selected"。 |
| SwipeView 命令出现绑定错误 | 使用 RelativeSource AncestorType,从项目模板内部访问 ViewModel。 |
评论
支持 Markdown