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

[Windows] Fix crash when navigating pages #25740

Merged
merged 7 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,31 @@ await CreateHandlerAndAddToWindow<ShellHandler>(shell, async (handler) =>
});
}

[Fact(DisplayName = "Navigate back and forth doesn't crash")]
public async Task NavigateBackAndForthDoesntCrash()
{
SetupBuilder();

var shell = await CreateShellAsync(shell =>
{
shell.CurrentItem = new ContentPage();
});

await CreateHandlerAndAddToWindow<ShellHandler>(shell, async (handler) =>
{
var secondPage = new ContentPage();

for (int i = 0; i < 5; i++)
{
await shell.Navigation.PushAsync(secondPage, false);
await Task.Delay(100);
await shell.Navigation.PopToRootAsync(false);
await Task.Delay(100);
}
Assert.NotNull(shell.Handler);
});
}

[Fact(DisplayName = "Shell Toolbar With Only MenuBarItems Is Visible")]
public async Task ShellToolbarWithOnlyMenuBarItemsIsVisible()
{
Expand Down
20 changes: 15 additions & 5 deletions src/Core/src/Platform/Windows/StackNavigationManager.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Animation;
Expand All @@ -17,6 +14,7 @@ public class StackNavigationManager
IMauiContext _mauiContext;
Frame? _navigationFrame;
Action? _pendingNavigationFinished;
ContentPresenter? _previousContent;
bool _connected;

protected NavigationRootManager WindowManager => _mauiContext.GetNavigationRootManager();
Expand Down Expand Up @@ -166,6 +164,14 @@ void OnNavigated(object sender, UI.Xaml.Navigation.NavigationEventArgs e)
VerticalAlignment = UI.Xaml.VerticalAlignment.Stretch
};

// There's some bug in our code, or the lifecycle of ContentControl, that is causing the content to
// never be removed from the parent...
if (_previousContent is not null)
{
_previousContent.Content = null;
_previousContent = null;
}

page.Content = presenter;
}
else
Expand All @@ -174,13 +180,15 @@ void OnNavigated(object sender, UI.Xaml.Navigation.NavigationEventArgs e)
}

// At this point if the Content isn't a ContentPresenter the user has replaced
// the conent so we just let them take control
// the content so we just let them take control
if (presenter == null || _currentPage == null)
return;

var platformPage = _currentPage.ToPlatform(MauiContext);

try
{
presenter.Content = _currentPage.ToPlatform(MauiContext);
presenter.Content = platformPage;
}
catch (Exception)
{
Expand All @@ -190,6 +198,8 @@ void OnNavigated(object sender, UI.Xaml.Navigation.NavigationEventArgs e)

_pendingNavigationFinished = () =>
{
_previousContent = presenter;

if (presenter?.Content is not FrameworkElement pc)
{
FireNavigationFinished();
Expand Down
Loading