Xamarin Forms CollectionView throwing NSInternalInconsistencyException

midhun_d_kumarmidhun_d_kumar Member ✭✭

I have a Xamarin forms project which consists of a ColectionView whose ItemSource is backed by a bindable property of type ObservableCollection in the ViewModel. Adding new items to the ObservableCollection is throwing NSInternalInconsistencyException, that too only on actual device whereas in the simulator it's working fine. Also if I create a new local parameter to hold the ItemSources values until all items are added to it and assigning this to the ItemSource bound property also works.

    ObservableCollection<ExploreUIDataSet> _exploreDataList = new ObservableCollection<ExploreUIDataSet>();

    public ObservableCollection<ExploreUIDataSet> ExploreDataList
    {
        get { return _exploreDataList; }
        set { _exploreDataList = value; OnPropertyChanged(nameof(ExploreDataList)); }
    }

ExploreDataList.Add() will trow NSInternalInconsistencyException. Creating a local variable and adding all values to it and assigning it back to ExploreDataList is working fine. In native ios projects, we used to handle such changes in source through batch updates. But in forms do we need to do that, especially when the CollectionView is backed by the observable collection. Also having a Stacklayout with BindabLayout.itemsource as the ExploreDataList works even when we add new items into the ObservableCollection.

ie the below code works

      <StackLayout Spacing="{DynamicResource Spacing10}"
                                 Padding="{DynamicResource ExploreMainStkPadding}"
                                 BindableLayout.ItemsSource="{Binding ExploreDataList}"
                                 BindableLayout.ItemTemplateSelector="{DynamicResource ExploreSelector}">
                    </StackLayout>

whereas the below CollectionView code fails

<CollectionView VerticalOptions="StartAndExpand" HorizontalOptions="StartAndExpand" ItemsSource="{Binding ExploreDataList}" ItemTemplate="{DynamicResource ExploreSelector}"/>

Answers

  • JuniorJiangJuniorJiang Member, Xamarin Team Xamurai

    Hi @midhun_d_kumar , have a look at this document how to refresh CollectionView .

  • midhun_d_kumarmidhun_d_kumar Member ✭✭

    @JuniorJiang In my scenario, we already have the data with me, no need for pull to refresh, the bindable property which is being used as a source for the collection view, am adding further items into it, thats when am getting the exception.

  • JuniorJiangJuniorJiang Member, Xamarin Team Xamurai

    Okey @midhun_d_kumar , could you share code about adding items and where adding them ?

  • midhun_d_kumarmidhun_d_kumar Member ✭✭
    private void GenerateExplorePage()
            {
                ExploreDataList = new ObservableCollection<ExploreUIDataSet>();
                SetBanners();
                SetCategoryData();
                //ExploreDataList = ExploreData;
            }
    
            private void SetBanners()
            {
                List<Banner> banners = DBService.GetDB().FetchBanners().ToList();
                ExploreDataList.Add(new ExploreUIDataSet()
                {
                    ViewData = banners,
                    ViewType = ExploreViewType.HSCROLLBANNER
                });
            }
    
            private void SetCategoryData()
            {
                Dictionary<Category, List<Product>> catProdMap = DBService.GetDB().FetchOfflineCategoryProductMap();
                List<Category> categories = catProdMap?.Keys.ToList();
                categories?.All((arg) =>
                {
                    arg.ExploreDetailsCommand = ExploreDetailsCommand;
                    return true;
                });
                int count = categories == null ? 0 : categories.Count > 4 ? 4 : categories.Count;//temp
                for (int index = 0; index < count; index++)
                {
                    //Title Section 
                    ExploreDataList.Add(new ExploreUIDataSet()
                    {
                        ViewType = ExploreViewType.HEADER,
                        ViewData = categories[index]
                    });
                    //Corresponding Section Products
                    List<Product> products = catProdMap[categories[index]];
                    products?.All((arg) =>
                    {
                        arg.LaunchCommand = ProductLaunchCommand;
                        return true;
                    });
                    if (products != null)
                    {
                        products.LastOrDefault().ItemMargin = Device.Idiom == TargetIdiom.Phone ? new Thickness(0, 0, 20, 0) : new Thickness(0, 0, 30, 0);
                    }
                    //until actual ui mapping, alternative categories are loaded as horizontal and coverflow items.
                    if (index % 2 == 0)
                    {
                        ExploreDataList.Add(new ExploreUIDataSet()
                        {
                            ViewData = new ObservableCollection<object>(products),
                            ViewType = ExploreViewType.HSCROLL
                        });
                    }
                    else
                    {
                        ExploreDataList.Add(new ExploreUIDataSet()
                        {
                            ViewData = GenerateDataForFlowList(products),
                            ViewType = ExploreViewType.HSCROLLFLOWVIEW
                        });
                    }
                }
                SetBrowseByCategory(categories.GetRange(count, categories.Count - count));
            }
    

    Here ExploreDataList is the property that is being used as the Source in Collectionview, Instead of updating the ExploreDataList if I use another property of the same type update it with all the required data and assign that to the ExploreDataList this will work else throwing the error

  • JuniorJiangJuniorJiang Member, Xamarin Team Xamurai
    edited November 25

    Hi @midhun_d_kumar , it seems that ExploreUIDataSet contains multi type data and not matching original data when adding . What is the deatil error logs ?

  • midhun_d_kumarmidhun_d_kumar Member ✭✭

    Hi, @JuniorJiang This is the ExploreUIDataSet Model mentioned below: Also, not sure about mismatch as the same was working fine with a bindable layout before, or if its something else could you please elaborate.

        public class ExploreUIDataSet : AbstractNpcObject
            {
                public object ViewData { get; set; }
                public ExploreViewType ViewType { get; set; }
                public int CardPosition;
                public int CarouselPosition
                {
                    get
                    {
                        return CardPosition;
                    }
                    set
                    {
                        CardPosition = value; OnPropertyChanged(nameof(CarouselPosition));
                    }
                }
            }
    

    Also, the code is working fine in a simulator and a few devices as well.
    Eg: Working fine in iPhone 7 plus. (13.2.3), iPad Air 2 (13.1.2)

    Throwing the below exception in iPhone 6 plus (12.4)
    Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: Invalid update: invalid number of items in section 0. The number of items contained in an existing section after the update (1) must be equal to the number of items contained in that section before the update (1), plus or minus the number of items inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out).

  • midhun_d_kumarmidhun_d_kumar Member ✭✭

    And in Android (Google pixel, Version: 10) am getting this exception

    Cannot access a disposed object.
    Object name: 'Xamarin.Forms.Platform.Android.GroupableItemsViewAdapter2[[Xamarin.Forms.GroupableItemsView, Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null],[Xamarin.Forms.Platform.Android.IGroupableItemsViewSource, Xamarin.Forms.Platform.Android, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]]'. Cannot access a disposed object. Object name: 'Xamarin.Forms.Platform.Android.GroupableItemsViewAdapter2[[Xamarin.Forms.GroupableItemsView, Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null],[Xamarin.Forms.Platform.Android.IGroupableItemsViewSource, Xamarin.Forms.Platform.Android, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]]'.

    For Android 10 device this is observed every single time whereas it was observed rarely in android 9 device.

  • JuniorJiangJuniorJiang Member, Xamarin Team Xamurai

    Okey @midhun_d_kumar , this seems code is no problem , it's related to version of mobile . In addition , do you use third party library in project ?

  • midhun_d_kumarmidhun_d_kumar Member ✭✭

    @JuniorJiang yes we are using few third-party libraries

  • midhun_d_kumarmidhun_d_kumar Member ✭✭

    @midhun_d_kumar said:
    Hi, @JuniorJiang This is the ExploreUIDataSet Model mentioned below: Also, not sure about mismatch as the same was working fine with a bindable layout before, or if its something else could you please elaborate.

        public class ExploreUIDataSet : AbstractNpcObject
            {
                public object ViewData { get; set; }
                public ExploreViewType ViewType { get; set; }
                public int CardPosition;
                public int CarouselPosition
                {
                    get
                    {
                        return CardPosition;
                    }
                    set
                    {
                        CardPosition = value; OnPropertyChanged(nameof(CarouselPosition));
                    }
                }
            }
    

    Also, the code is working fine in a simulator and a few devices as well.
    Eg: Working fine in iPhone 7 plus. (13.2.3), iPad Air 2 (13.1.2)

    Throwing the below exception in iPhone 6 plus (12.4), iPad mini 3 (12.3.1)
    Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: Invalid update: invalid number of items in section 0. The number of items contained in an existing section after the update (1) must be equal to the number of items contained in that section before the update (1), plus or minus the number of items inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out).

  • JuniorJiangJuniorJiang Member, Xamarin Team Xamurai

    @midhun_d_kumar Okey , I think this problem should be related to some permissions or methods used from third-party library . From your shred code , not finding problems about version of mobile framework .

  • myPhoenixmyPhoenix ZAMember ✭✭

    This is still a problem, and we do not use 3rd party libraries

Sign In or Register to comment.