Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS CarouselView crashes with "MauiContext should have been set on parent." #23278

Open
ESO-ST opened this issue Jun 26, 2024 · 7 comments · Fixed by #23408
Open

iOS CarouselView crashes with "MauiContext should have been set on parent." #23278

ESO-ST opened this issue Jun 26, 2024 · 7 comments · Fixed by #23408
Assignees
Labels
area-controls-collectionview CollectionView, CarouselView, IndicatorView i/regression This issue described a confirmed regression on a currently supported version partner/cat 😻 this is an issue that impacts one of our partners or a customer our advisory team is engaged with platform/iOS 🍎 t/bug Something isn't working
Milestone

Comments

@ESO-ST
Copy link

ESO-ST commented Jun 26, 2024

Description

When a CarouselView is in a Mopups popup page, if we try to scroll through it we will get a crash

2024-06-20 20:59:32.172790+0100 MyProject[4427:14609335] Unhandled managed exception: MauiContext should have been set on parent. (System.InvalidOperationException)
   at Microsoft.Maui.Platform.ElementExtensions.ToPlatform(IElement view)
   at Microsoft.Maui.Handlers.LayoutHandler.Remove(IView child)
   at Microsoft.Maui.Handlers.LayoutHandler.MapRemove(ILayoutHandler handler, ILayout layout, Object arg)
   at Microsoft.Maui.CommandMapper`2.<>c__DisplayClass6_0[[Microsoft.Maui.ILayout, Microsoft.Maui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Microsoft.Maui.ILayoutHandler, Microsoft.Maui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].<Add>b__0(IElementHandler h, IElement v, Object o)
   at Microsoft.Maui.CommandMapper.InvokeCore(String key, IElementHandler viewHandler, IElement virtualView, Object args)
   at Microsoft.Maui.CommandMapper.Invoke(IElementHandler viewHandler, IElement virtualView, String property, Object args)
   at Microsoft.Maui.Handlers.ElementHandler.Invoke(String command, Object args)
   at Microsoft.Maui.Controls.Layout.NotifyHandler(String action, Int32 index, IView view)
   at Microsoft.Maui.Controls.Layout.OnRemove(Int32 index, IView view)
   at Microsoft.Maui.Controls.FlexLayout.OnRemove(Int32 index, IView view)
   at Microsoft.Maui.Controls.Layout.RemoveAt(Int32 index)
   at Microsoft.Maui.Controls.BindableLayout.RemoveAt(IBindableLayout layout, Int32 index)
   at Microsoft.Maui.Controls.BindableLayoutController.ClearChildren(IBindableLayout layout)
   at Microsoft.Maui.Controls.BindableLayoutController.CreateChildren()
   at Microsoft.Maui.Controls.BindableLayoutController.SetItemsSource(IEnumerable itemsSource)
   at Microsoft.Maui.Controls.BindableLayoutController.set_ItemsSource(IEnumerable value)
   at Microsoft.Maui.Controls.BindableLayout.<>c.<.cctor>b__24_0(BindableObject b, Object o, Object n)
   at Microsoft.Maui.Controls.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, SetterSpecificity specificity, Boolean silent)
   at Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.BindingExpression.ApplyCore(Object sourceObject, BindableObject target, BindableProperty property, Boolean fromTarget, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.BindingExpression.Apply(Object sourceObject, BindableObject target, BindableProperty property, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.Binding.Apply(Object context, BindableObject bindObj, BindableProperty targetProperty, Boolean fromBindingContextChanged, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.BindableObject.ApplyBindings(Boolean skipBindingContext, Boolean fromBindingContextChanged)
   at Microsoft.Maui.Controls.BindableObject.BindingContextPropertyChanged(BindableObject bindable, Object oldvalue, Object newvalue)
   at Microsoft.Maui.Controls.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, SetterSpecificity specificity, Boolean silent)
   at Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.BindableObject.SetValue(BindableProperty property, Object value)
   at Microsoft.Maui.Controls.BindableObject.set_BindingContext(Object value)
   at Microsoft.Maui.Controls.Handlers.Items.TemplatedCell.Unbind()
   at Microsoft.Maui.Controls.Handlers.Items.TemplatedCell.PrepareForReuse()
   at UIKit.UICollectionView.DequeueReusableCell(NSString reuseIdentifier, NSIndexPath indexPath) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/build/dotnet/ios/generated-sources/UIKit/UICollectionView.g.cs:line 234
   at UIKit.UICollectionView.DequeueReusableCell(String reuseIdentifier, NSIndexPath indexPath) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/UIKit/UICollectionView.cs:line 23
   at Microsoft.Maui.Controls.Handlers.Items.ItemsViewController`1[[Microsoft.Maui.Controls.CarouselView, Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].GetCell(UICollectionView collectionView, NSIndexPath indexPath)
   at Microsoft.Maui.Controls.Handlers.Items.CarouselViewController.GetCell(UICollectionView collectionView, NSIndexPath indexPath)
   at UIKit.UIApplication.UIApplicationMain(Int32 argc, String[] argv, IntPtr principalClassName, IntPtr delegateClassName) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/UIKit/UIApplication.cs:line 58
   at UIKit.UIApplication.Main(String[] args, Type principalClass, Type delegateClass) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/UIKit/UIApplication.cs:line 94

Steps to Reproduce

  1. Press the button "open mopups popup" to open the Mopups popup page.
  2. scroll through the carousel.

Link to public reproduction project repository

https://github.com/ESO-ST/CarouselViewCrash

Version with bug

8.0.60 SR6

Is this a regression from previous behavior?

Yes, this used to work in .NET MAUI

Last version that worked well

8.0.40 SR5

Affected platforms

iOS

Affected platform versions

No response

Did you find any workaround?

No response

Relevant log output

No response

@ESO-ST ESO-ST added the t/bug Something isn't working label Jun 26, 2024
Copy link
Contributor

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one and thumbs upping the other issue to help us prioritize it. Thank you!

Open similar issues:

Closed similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.

@samhouts samhouts added platform/iOS 🍎 potential-regression This issue described a possible regression on a currently supported version., verification pending labels Jun 26, 2024
@PureWeen PureWeen added this to the .NET 8 SR7 milestone Jun 26, 2024
@PureWeen PureWeen self-assigned this Jun 26, 2024
@PureWeen PureWeen added the area-controls-collectionview CollectionView, CarouselView, IndicatorView label Jun 27, 2024
@RoiChen001 RoiChen001 added s/verified Verified / Reproducible Issue ready for Engineering Triage s/triaged Issue has been reviewed i/regression This issue described a confirmed regression on a currently supported version labels Jun 27, 2024
@RoiChen001
Copy link
Collaborator

I can repro this issue at iOS platform on the latest 17.11.0 Preview 2.1(8.0.60). But the problem doesn't exist on 8.0.40.
image

@samhouts samhouts removed the potential-regression This issue described a possible regression on a currently supported version., verification pending label Jun 27, 2024
@xyeie
Copy link

xyeie commented Jul 1, 2024

I can repro this issue at iOS platform on the latest 17.10.2(8.0.61)

@mikeparker104 mikeparker104 added the partner/cat 😻 this is an issue that impacts one of our partners or a customer our advisory team is engaged with label Jul 1, 2024
@PureWeen
Copy link
Member

PureWeen commented Jul 2, 2024

So we can probably add a fix for this on our side

But it looks like MopUPs is wiring up to all our classes and calling disconnecthandler.
Most likely to workaround memory leaks

image

@samhouts samhouts removed s/verified Verified / Reproducible Issue ready for Engineering Triage s/triaged Issue has been reviewed labels Jul 3, 2024
@ESO-ST
Copy link
Author

ESO-ST commented Jul 5, 2024

@PureWeen tested on the latest nightly build 8.0.70-ci.net8.24355.1, we now get this exception when trying to scroll the carousel

Index was outside the bounds of the array.

   at Microsoft.Maui.Handlers.LayoutHandler.Remove(IView child)
   at Microsoft.Maui.Handlers.LayoutHandler.MapRemove(ILayoutHandler handler, ILayout layout, Object arg)
   at Microsoft.Maui.CommandMapper`2.<>c__DisplayClass6_0[[Microsoft.Maui.ILayout, Microsoft.Maui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Microsoft.Maui.ILayoutHandler, Microsoft.Maui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].<Add>b__0(IElementHandler h, IElement v, Object o)
   at Microsoft.Maui.CommandMapper.InvokeCore(String key, IElementHandler viewHandler, IElement virtualView, Object args)
   at Microsoft.Maui.CommandMapper.Invoke(IElementHandler viewHandler, IElement virtualView, String property, Object args)
   at Microsoft.Maui.Handlers.ElementHandler.Invoke(String command, Object args)
   at Microsoft.Maui.Controls.Layout.NotifyHandler(String action, Int32 index, IView view)
   at Microsoft.Maui.Controls.Layout.OnRemove(Int32 index, IView view)
   at Microsoft.Maui.Controls.FlexLayout.OnRemove(Int32 index, IView view)
   at Microsoft.Maui.Controls.Layout.RemoveAt(Int32 index)
   at Microsoft.Maui.Controls.BindableLayout.RemoveAt(IBindableLayout layout, Int32 index)
   at Microsoft.Maui.Controls.BindableLayoutController.ClearChildren(IBindableLayout layout)
   at Microsoft.Maui.Controls.BindableLayoutController.CreateChildren()
   at Microsoft.Maui.Controls.BindableLayoutController.SetItemsSource(IEnumerable itemsSource)
   at Microsoft.Maui.Controls.BindableLayoutController.set_ItemsSource(IEnumerable value)
   at Microsoft.Maui.Controls.BindableLayout.<>c.<.cctor>b__24_0(BindableObject b, Object o, Object n)
   at Microsoft.Maui.Controls.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, SetterSpecificity specificity, Boolean silent)
   at Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.BindingExpression.ApplyCore(Object sourceObject, BindableObject target, BindableProperty property, Boolean fromTarget, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.BindingExpression.Apply(Object sourceObject, BindableObject target, BindableProperty property, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.Binding.Apply(Object context, BindableObject bindObj, BindableProperty targetProperty, Boolean fromBindingContextChanged, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.BindableObject.ApplyBindings(Boolean skipBindingContext, Boolean fromBindingContextChanged)
   at Microsoft.Maui.Controls.BindableObject.BindingContextPropertyChanged(BindableObject bindable, Object oldvalue, Object newvalue)
   at Microsoft.Maui.Controls.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, SetterSpecificity specificity, Boolean silent)
   at Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.BindableObject.SetValue(BindableProperty property, Object value)
   at Microsoft.Maui.Controls.BindableObject.set_BindingContext(Object value)
   at Microsoft.Maui.Controls.Handlers.Items.TemplatedCell.Unbind()
   at Microsoft.Maui.Controls.Handlers.Items.TemplatedCell.PrepareForReuse()
   at UIKit.UICollectionView.DequeueReusableCell(NSString reuseIdentifier, NSIndexPath indexPath) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/build/dotnet/ios/generated-sources/UIKit/UICollectionView.g.cs:line 234
   at UIKit.UICollectionView.DequeueReusableCell(String reuseIdentifier, NSIndexPath indexPath) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/UIKit/UICollectionView.cs:line 23
   at Microsoft.Maui.Controls.Handlers.Items.ItemsViewController`1[[Microsoft.Maui.Controls.CarouselView, Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].GetCell(UICollectionView collectionView, NSIndexPath indexPath)
   at Microsoft.Maui.Controls.Handlers.Items.CarouselViewController.GetCell(UICollectionView collectionView, NSIndexPath indexPath)
   at UIKit.UIApplication.UIApplicationMain(Int32 argc, String[] argv, IntPtr principalClassName, IntPtr delegateClassName) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/UIKit/UIApplication.cs:line 58
   at UIKit.UIApplication.Main(String[] args, Type principalClass, Type delegateClass) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/UIKit/UIApplication.cs:line 94
   at CarouselViewCrash.Program.Main(String[] args) in C:\Users\ST\source\repos\CarouselViewCrash\CarouselViewCrash\Platforms\iOS\Program.cs:line 13

@PureWeen PureWeen reopened this Jul 5, 2024
@PureWeen
Copy link
Member

PureWeen commented Jul 5, 2024

Hmmm

I'm going to revert my previous commit,
I'm not sure if I can quick fix this one unfortunately.
Because Mopups is removing the platformview from the virtualView before the code calls back into the layouthandlers remove code. The layout handler can't really figure out where that view is located in the hierarchy.

I'll have to revisit this next week to see if there's a path we can implement.
I'd like to just fix it so we call the remove code in the handler before removing it from the logical tree, but, not sure how impactful that will be.

My current suggestions are

@PureWeen
Copy link
Member

PureWeen commented Jul 5, 2024

@ESO-ST based on your sample it looks like this works

       private static void RegisterRenderers(IMauiHandlersCollection handlersCollection)
        {

#if IOS
            LayoutHandler.CommandMapper.ModifyMapping(nameof(ILayoutHandler.Remove), OnThing);
#endif
        }

        private static void OnThing(ILayoutHandler handler, Microsoft.Maui.ILayout layout, object? arg3, Action<IElementHandler, IElement, object?>? action)
        {
            if (arg3 is LayoutHandlerUpdate args && args.View.Handler is null)
            {
                // if you're not messing with the zindexes then you can just remove the platformview via the index

                #if IOS

                (layout.Handler as IPlatformViewHandler).PlatformView.Subviews[args.Index].RemoveFromSuperview();

                #endif
            }
            else
            {
                action?.Invoke(handler, layout, arg3);
            }
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-controls-collectionview CollectionView, CarouselView, IndicatorView i/regression This issue described a confirmed regression on a currently supported version partner/cat 😻 this is an issue that impacts one of our partners or a customer our advisory team is engaged with platform/iOS 🍎 t/bug Something isn't working
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

6 participants