Skip to content

Shell.OnNavigated not called for route navigation #34662

Description

@ArcanoxDragon

Description

On 10.0.50 and above, the Shell.OnNavigated(ShellNavigatedEventArgs args) method is not invoked when a navigation is triggered using the Shell.Current.GoToAsync method.

In my company's app, we register a number of our pages using AddTransientWithShellRoute from CommunityToolkit.Maui (e.g. AddTransientWithShellRoute<MyPage, MyViewModel>(), which adds a route called "MyPage" for that page). Our app's shell is a subclass of Shell named AppShell.

When we need to navigate, we call await Shell.Current.GoToAsync("MyPage", ...) to navigate to the correct page. On 10.0.41, this navigation causes our AppShell class's OnNavigated method to be called once the navigation is performed. We use this to handle post-navigation events.

On 10.0.50 and above, OnNavigated is no longer called for such navigations on iOS. It works fine on Android. Our app does not target Mac Catalyst, so I am unsure if this bug also occurs there.

I have traced this to the IShellController.UpdateCurrentState implementation in Shell.cs:

void IShellController.UpdateCurrentState(ShellNavigationSource source)
{
var oldState = CurrentState;
var shellItem = CurrentItem;
var shellSection = shellItem?.CurrentItem;
var shellContent = shellSection?.CurrentItem;
var stack = shellSection?.Stack;
var modalStack = shellSection?.Navigation?.ModalStack;
var result = ShellNavigationManager.GetNavigationState(shellItem, shellSection, shellContent, stack, modalStack);
if (result?.Location != oldState?.Location)
{
SetValueFromRenderer(CurrentStatePropertyKey, result);
_navigationManager.HandleNavigated(new ShellNavigatedEventArgs(oldState, CurrentState, source));
}
}

After the navigation occurs, result?.Location and oldState?.Location both hold the same value (the old page), so it never calls HandleNavigated.

For example, after signing in, the app changes the shell's CurrentItem to one of the root items - suppose this item has a route of /RootItem/RootContent. The user can select an item on this root page that will result in await Shell.Current.GoToAsync("MyPage", ...).

Once this navigation occurs, UpdateCurrentState is called, and both result?.Location and oldState?.Location evaluate to /RootItem/RootContent, instead of what I would expect to see, which would be result?.Location evaluating to /MyPage.

Steps to Reproduce

  • Create a simple shell app
  • Add one page to the shell directly as a shell item
  • Register another page with a route instead of a shell item (either using CommunityToolkit, or just by using Routing.RegisterRoute)
  • Add a way for the first page (the direct shell item) to navigate to the second page (the routed page) using Shell.Current.GoToAsync
  • Override OnNavigated in the shell class, and print a debug statement when it is called
  • Run the app on iOS and perform the navigation. Observe that OnNavigated is not called.

Link to public reproduction project repository

No response

Version with bug

10.0.50

Is this a regression from previous behavior?

Yes, this used to work in .NET MAUI

Last version that worked well

10.0.40

Affected platforms

iOS

Affected platform versions

No response

Did you find any workaround?

No response

Relevant log output

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-controls-shellShell Navigation, Routes, Tabs, Flyoutpartner/syncfusionIssues / PR's with Syncfusion collaborationplatform/iospotential-regressionThis issue described a possible regression on a currently supported version., verification pendingregressed-in-10.0.50s/triagedIssue has been revieweds/verifiedVerified / Reproducible Issue ready for Engineering Triaget/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions