mcpField
M
maui-collectionview

maui-collectionview

github.com/davidortinau开发17664 次安装17 周前更新
代码仓库

关于 maui-collectionview

面向 .NET MAUI 的 CollectionView 技能,介绍如何展示可滚动的数据列表和网格。内容涵盖绑定、刷新和增量加载,并说明避免常见界面问题及性能问题的布局与线程做法。

主要功能

  1. 01使用 ObservableCollection 绑定数据
  2. 02配置不含 ViewCell 的项目模板
  3. 03通过祖先绑定使用 SwipeView
  4. 04添加下拉刷新和增量加载
  5. 05选择支持虚拟化的布局
  6. 06优化尺寸测量与 UI 线程更新

适用场景

  1. 01创建可滚动且数据会变化的列表或网格
  2. 02添加滑动命令和下拉刷新
  3. 03滚动列表时加载更多项目
  4. 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