You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IsGrouped为True的CollectionView,RemainingItemsThresholdReachedCommand多平台失效求助

问题

我给IsGrouped=True的CollectionView设置了无限滚动逻辑,在Android平台运行正常,但iOS、Windows和MacCatalyst平台上,RemainingItemsThresholdReachedCommand命令完全不执行。现在应用需要从云端获取的数据量越来越大,没法一次性加载所有数据到集合里。请问怎么解决这个问题?如果这是个Bug,有没有不需要设置按钮逐页加载的替代方案?

我的XAML代码如下:

<Grid
    Grid.Row="3"
    VerticalOptions="Fill">

    <CollectionView
        ItemsSource="{Binding ListItemsGroup}"
        SelectionMode="Single"                   
        SelectedItem="{Binding CurrentItem, Mode=TwoWay}"
        RemainingItemsThreshold="2"
        RemainingItemsThresholdReachedCommand="{Binding LoadMoreItemsCommand}"
        IsGrouped="True">

解决方案

1. 手动监听滚动事件替代内置命令

分组模式下RemainingItemsThresholdReachedCommand存在跨平台兼容性问题,可通过监听Scrolled事件实现加载逻辑:

  • 在XAML中给CollectionView添加事件绑定:
    <CollectionView
        ...
        Scrolled="CollectionView_Scrolled">
    
  • 后台代码实现滚动判断逻辑:
    private void CollectionView_Scrolled(object sender, ItemsViewScrolledEventArgs e)
    {
        var collectionView = sender as CollectionView;
        if (collectionView == null || collectionView.ItemsSource == null) return;
    
        // 计算分组后的总项数(含组头)
        var totalItems = collectionView.ItemsSource.Cast<IGrouping<object, object>>()
            .Sum(group => group.Count() + 1); // +1对应每组的组头
    
        // 已滚动可见的最后一项索引+1为已加载项数
        var loadedItems = e.LastVisibleItemIndex + 1;
    
        // 剩余项数达到阈值时触发加载
        if (totalItems - loadedItems <= 2)
        {
            var viewModel = BindingContext as YourViewModel;
            viewModel?.LoadMoreItemsCommand.Execute(null);
        }
    }
    
    注:需确保分组模型实现IGrouping接口,否则根据自定义分组结构调整总项数计算方式。

2. 规范分组数据源实现

部分平台对分组数据源的类型要求严格,需确保ListItemsGroup满足:

  • 实现IEnumerable<IGrouping<TKey, TItem>>接口
  • 每个分组项正确包含Key属性和可枚举子项
  • 避免使用未实现标准接口的自定义分组类,否则平台无法正确计算剩余项数

3. 加载新数据后强制刷新布局

每次加载完新数据后,在UI线程调用InvalidateLayout(),强制平台重新计算滚动状态:

// 在ViewModel的LoadMoreItemsCommand执行完成后
MainThread.BeginInvokeOnMainThread(() =>
{
    YourCollectionView.InvalidateLayout();
});

4. iOS/MacCatalyst自定义渲染器

若上述方法无效,可针对iOS平台编写自定义渲染器,直接监听原生滚动事件:

[assembly: ExportRenderer(typeof(CollectionView), typeof(CustomGroupedCollectionViewRenderer))]
namespace YourApp.iOS.Renderers
{
    public class CustomGroupedCollectionViewRenderer : CollectionViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<ItemsView> e)
        {
            base.OnElementChanged(e);
            if (Control != null)
            {
                Control.ScrollView.DidScroll += ScrollView_DidScroll;
            }
        }

        private void ScrollView_DidScroll(object sender, EventArgs e)
        {
            var scrollView = sender as UIScrollView;
            var collectionView = Element as CollectionView;
            if (scrollView == null || collectionView == null) return;

            // 距离底部100pt时触发加载
            var isNearBottom = scrollView.ContentOffset.Y + scrollView.Frame.Height 
                >= scrollView.ContentSize.Height - 100;
            if (isNearBottom)
            {
                var viewModel = collectionView.BindingContext as YourViewModel;
                viewModel?.LoadMoreItemsCommand.Execute(null);
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者ImproveSoftware

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 07:53:17