dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22.15k stars 1.74k forks source link

Error when adding to ObservableCollection #21374

Open mooola opened 7 months ago

mooola commented 7 months ago

Description

Immediately after upgrading to Maui Controls 8.0.0.10, we have been getting an error when adding items to ObservableCollection

Steps to Reproduce

  1. Open Repro project
  2. Add breakpoint to line 73 of MainPageViewModel
  3. Click "Populate Person" button
  4. Should see the error message: Objective-C exception thrown. Name: NSInvalidArgumentException Reason: The invalidation context ((null)) sent to -[UICollectionViewFlowLayout invalidateLayoutWithContext:] is not an instance of type UICollectionViewFlowLayoutInvalidationContext or a subclass. Collection view: <Microsoft_Maui_Controls_Handlers_Items_MauiCollectionView: 0x11776b600; baseClass = UICollectionView; frame = (0 0; 0 1048.5); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x28075e250>; backgroundColor = UIExtendedGrayColorSpace 0 0; layer = <CALayer: 0x284913720>; contentOffset: {0, 0}; contentSize: {0, 0}; adjustedContentInset: {0, 0, 0, 0}; layout: <Microsoft_Maui_Controls_Handlers_Items_ListViewLayout: 0x102fdda30>; dataSource: <Microsoft_Maui_Controls_Handlers_Items_ReorderableItemsViewController_1: 0x102fd6be0>>

Link to public reproduction project repository

https://github.com/mooola/MauiIssues

Version with bug

8.0.10 SR3

Is this a regression from previous behavior?

Yes, this used to work in .NET MAUI

Last version that worked well

8.0.7 SR2

Affected platforms

iOS

Affected platform versions

No response

Did you find any workaround?

Changing line 40 in MainPage.xaml to Auto "fixes" the issue.

Relevant log output

No response

Zhanglirong-Winnie commented 7 months ago

Verified this issue with Visual Studio 17.10.0 Preview 2&17.6.10 build 428. Not repro on iOS platform with sample project. Maui Controls: 8.0.10/ 8.0.14/8.0.20-nightly.10336+sha.d03a2c66aa-azdo.9265184 https://github.com/mooola/MauiIssues image

adrian-ovidiu commented 7 months ago

I get this error in 8.0.10 and in 8.0.14 too. Worked well in 8.0.7. The workaround is not working for me in my project (changing * to Auto).

mooola commented 7 months ago

Issue is still present in 8.0.20-nightly.10336+sha.d03a2c66aa-azdo.9265184

PureWeen commented 7 months ago

@mooola on your sample why do you have the WidthRequest on the border set to 0.5?

https://github.com/mooola/MauiIssues/blob/main/MauiApp3/MainPage.xaml#L36

If I set that border to something like 100 then I don't get the exception.

mooola commented 7 months ago

@PureWeen - I created the sample exactly how we found it in our app. I don't have an explanation as to why it is set to 0.5, but in our project when we removed that property entirely, we didn't get the exception. When we tried removing the property in our sample, we still got the exception so I didn't mention it. We are seeing this issue on multiple CollectionViews in our app. One that is contained in grids, doesn't have a border with a WidthRequests.

mooola commented 7 months ago

Something else we found was changing how the ObservableCollection was populated didn't cause the error.

private void PopulatePerson(object parameter)
{
    IsPersonVisible = true;

    try
    {
        List<Person> people = new List<Person>();

        for (int j = 0; j < 10; j++)
        {
            people.Add(new Person { Name = "Person " + j });
        }
        People = new ObservableCollection<Person>(people);
    }
    catch (Exception ex) 
    { 
        Console.WriteLine(ex.ToString());
    }
}
jsuarezruiz commented 7 months ago

More info, cannot reproduce it on Catalyst.

jsuarezruiz commented 6 months ago

2024-04-03 08:58:43.796 Xamarin.PreBuilt.iOS[4227:1117230] ObjCRuntime.ObjCException: Objective-C exception thrown. Name: NSInvalidArgumentException Reason: The invalidation context ((null)) sent to -[UICollectionViewFlowLayout invalidateLayoutWithContext:] is not an instance of type UICollectionViewFlowLayoutInvalidationContext or a subclass. Collection view: <Microsoft_Maui_Controls_Handlers_Items_MauiCollectionView: 0x1153bae00; baseClass = UICollectionView; frame = (0 0; 0 710); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x302e957a0>; backgroundColor = UIExtendedGrayColorSpace 0 0; layer = <CALayer: 0x30296b9e0>; contentOffset: {0, 0}; contentSize: {0, 0}; adjustedContentInset: {0, 0, 0, 0}; layout: <Microsoft_Maui_Controls_Handlers_Items_ListViewLayout: 0x10a59ec40>; dataSource: <Microsoft_Maui_Controls_Handlers_Items_ReorderableItemsViewController_1: 0x104f8dbb0>>

bronteq commented 6 months ago

Something else we found was changing how the ObservableCollection was populated didn't cause the error.

private void PopulatePerson(object parameter)
{
    IsPersonVisible = true;

    try
    {
        List<Person> people = new List<Person>();

        for (int j = 0; j < 10; j++)
        {
            people.Add(new Person { Name = "Person " + j });
        }
        People = new ObservableCollection<Person>(people);
    }
    catch (Exception ex) 
    { 
        Console.WriteLine(ex.ToString());
    }
}

This workaround seems the same of these similar issues, maybe the problem affects more platforms? https://github.com/dotnet/maui/issues/20037 https://github.com/dotnet/maui/issues/18481

PureWeen commented 6 months ago

Something else we found was changing how the ObservableCollection was populated didn't cause the error.

private void PopulatePerson(object parameter)
{
    IsPersonVisible = true;

    try
    {
        List<Person> people = new List<Person>();

        for (int j = 0; j < 10; j++)
        {
            people.Add(new Person { Name = "Person " + j });
        }
        People = new ObservableCollection<Person>(people);
    }
    catch (Exception ex) 
    { 
        Console.WriteLine(ex.ToString());
    }
}

This workaround seems the same of these similar issues, maybe the problem affects more platforms? #20037 #18481

It's fairly platform independent why this would be causing issues.

PureWeen commented 6 months ago

@PureWeen - I created the sample exactly how we found it in our app. I don't have an explanation as to why it is set to 0.5, but in our project when we removed that property entirely, we didn't get the exception. When we tried removing the property in our sample, we still got the exception so I didn't mention it. We are seeing this issue on multiple CollectionViews in our app. One that is contained in grids, doesn't have a border with a WidthRequests.

Can you include a sample where this is crashing, and you aren't setting the Width to zero?

As far as we can tell this exception is fairly limited to scenarios where the CoillectionView is measuring to a zero width which is causing a strange invalidation to happen.

We could throw a couple things in that seem to avoid the crash, but I worry those are only fixing symptoms and you'll still get crashes for your other scenarios.

DrJShoff commented 4 months ago

For me, setting ItemSizingStrategy="MeasureFirstItem" on the CollectionView resolves the issue. Just as mentioned in this old bug report for Xamarin: https://github.com/xamarin/Xamarin.Forms/issues/13323

PureWeen commented 2 months ago

@Redth lets see if this is resolved by the new CV Handlers

https://github.com/dotnet/maui/pull/23928