Skip to content

[Android] Fix the Setting Content of ContentView through style would crash on parent change #29931

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

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
65 changes: 65 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue11812.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace Maui.Controls.Sample.Issues;

[Issue(IssueTracker.Github, 11812, "Setting Content of ContentView through style would crash on parent change", PlatformAffected.Android)]
public class Issue11812 : ContentPage
{
ContentView _mainContentView;
public Issue11812()
{
var button = new Button
{
Text = "Add ContentView",
HorizontalOptions = LayoutOptions.Center,
AutomationId = "ChangeInnerContent"
};
button.Clicked += OnButtonClicked;

_mainContentView = new ContentView();
_mainContentView.Content = new Issue11812InnerContentView();

var layout = new VerticalStackLayout
{
Spacing = 25,
Padding = new Thickness(30, 0),
VerticalOptions = LayoutOptions.Center,
Children =
{
button,
_mainContentView
}
};

Content = layout;
}
private void OnButtonClicked(object sender, EventArgs e)
{
_mainContentView.Content = new Issue11812InnerContentView() { BackgroundColor = Colors.Red };
}
}

public class Issue11812InnerContentView : ContentView
{
public Issue11812InnerContentView()
{
Application.Current.Resources ??= new ResourceDictionary();

if (!Application.Current.Resources.ContainsKey("SubContentStyle"))
{
Application.Current.Resources["SubContentStyle"] = new Style(typeof(ContentView))
{
Setters =
{
new Setter
{
Property = ContentView.ContentProperty,
Value = new Label { Text = "SubContent" }
}
}
};
}
Style = (Style)Application.Current.Resources["SubContentStyle"];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#if TEST_FAILS_ON_WINDOWS // test fails on windows , see https://github.com/dotnet/maui/issues/29930
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues;

public class Issue11812 : _IssuesUITest
{
public Issue11812(TestDevice device) : base(device) { }

public override string Issue => "Setting Content of ContentView through style would crash on parent change";

[Test]
[Category(UITestCategories.Border)]
public void InnerContentViewShouldNotCrashWhenDynamicallyChange()
{
App.WaitForElement("ChangeInnerContent");
App.Tap("ChangeInnerContent");
App.WaitForElement("ChangeInnerContent");
}
}
#endif
7 changes: 6 additions & 1 deletion src/Core/src/Handlers/Border/BorderHandler.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ static partial void UpdateContent(IBorderHandler handler)
handler.PlatformView.RemoveAllViews();

if (handler.VirtualView.PresentedContent is IView view)
handler.PlatformView.AddView(view.ToPlatform(handler.MauiContext));
{
var platformView = view.ToPlatform(handler.MauiContext);
// Ensure the view is detached from any existing parent before adding it
platformView.RemoveFromParent();
handler.PlatformView.AddView(platformView);
}
}

public static partial void MapHeight(IBorderHandler handler, IBorderView border)
Expand Down
1 change: 1 addition & 0 deletions src/Core/src/Handlers/Border/BorderHandler.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ static partial void UpdateContent(IBorderHandler handler)
if (handler.VirtualView.PresentedContent is IView content)
{
var platformContent = content.ToPlatform(handler.MauiContext);
platformContent.RemoveFromSuperview();

// If the content is a UIScrollView, we need a container to handle masks and clip shapes effectively.
if (platformContent is UIScrollView)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ static void UpdateContent(IContentViewHandler handler)
handler.PlatformView.RemoveAllViews();

if (handler.VirtualView.PresentedContent is IView view)
handler.PlatformView.AddView(view.ToPlatform(handler.MauiContext));
{
var platformView = view.ToPlatform(handler.MauiContext);
// Ensure the view is detached from any existing parent before adding it
platformView.RemoveFromParent();
handler.PlatformView.AddView(platformView);
}
}

public static partial void MapContent(IContentViewHandler handler, IContentView page)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ static void UpdateContent(IContentViewHandler handler)
if (handler.VirtualView.PresentedContent is IView view)
{
var platformView = view.ToPlatform(handler.MauiContext);
platformView.RemoveFromSuperview();
handler.PlatformView.AddSubview(platformView);

if (view.FlowDirection == FlowDirection.MatchParent)
Expand Down