Weird navigation in HamburgerMenu sample project from Prism-Samples-Forms

JacobEgnerJacobEgner Member ✭✭

(The forum does not allow me to paste links, so I apologize for the inconvenience of neutered links.)

The Prism library has a Prism-Samples-Forms[1] repo with a HamburgerMenu project. The HamburgerMenu sample has some login stuff, then lets you navigate between {ViewA,ViewB,ViewC} via buttons on a master page. Even within the simple navigation of the HamburgerMenu sample, I'm confused about what is going on.

I've modified the HamburgerMenu sample to show the user more info about the navigation stack and hosted the code at this HamburgerMenuMystery[2] repo.

One rather general question is: What exactly happens when you do a NavigationService.NavigateAsync("NavigationPage/SomeContentPage")? It causes you to navigate to SomeContentPage that is wrapped in a NavigationPage (so you get navigation icon, title, and toolbar items shown), right? I see this sort of "NavigationPage/SomeContentPage" a lot in Prism apps, but I've never seen an explanation of what it does nor guidelines about when to do/not-do it.

Some very specific questions about HamburgerMenuMystery behavior...

  • App.xaml.cs navigates to "/Index/Navigation/ViewA?message=InitialNav" ("Index" is an alias for MainPage, a MasterDetailPage), so when you start the app you are navigated to ViewA, which displays to the user Prism's GetNavigationUriPath and Xamarin's NavigationStack.

    • In ViewAViewModel, Prism's _navigationService.GetNavigationUriPath() returns "/Navigation/ViewA"; why is "/Index" absent?

    • In ViewA.xaml.cs, Xamarin's Navigation.NavigationStack is "/ViewA" (and the ModalStack is empty); why is "/Index" absent? Why does the Xamarin NavigationStack differ from Prism's GetNavigationUriPath?

(see first picture in repo README.md [3])

  • If you then click the hamburger icon so you get the MainPage master page, and click the "N/A" button so MainPageViewModel does a _navigationService.NavigateAsync("Navigation/ViewA?message=NA")...

    • Prism's GetNavigationUriPath returns "/Index/Navigation/ViewA"; why does "Index" appear now and not before?

(see second picture in repo README.md [3])

  • If you then click the hamburger icon and then click the "N/B" button, so the MainPageViewModel does a _navigationService.NavigateAsync("Navigation/ViewB?message=NB")...

    • Prism's GetNavigationUriPath returns "/Index/Navigation/ViewA/Navigation?useModalNavigation=true/ViewB"; why the useModalNavigation=true, especially considering that MainPageViewModel uses useModalNavigation: false when calling NavigateAsync?
    • Xamarin's Navigation.NavigationStack is simply "/ViewB" and ModalStack is again empty; why are these stacks so different from what GetNavigationUriPath indicates?

(see third picture in repo README.md [3])

[1] Prism-Samples-Forms, github.com/PrismLibrary/Prism-Samples-Forms

[2] HamburgerMenuMystery, github.com/jmegner/HamburgerMenuMystery

[3] HamburgerMenuMystery README.md, github.com/jmegner/HamburgerMenuMystery#hamburger-menu-mystery

Best Answer

Answers

  • JacobEgnerJacobEgner Member ✭✭

    Also, let me add that my experiences with HamburgerMenuMystery seem to contradict the official Prism doc ( prismlibrary.github.io/docs/xamarin-forms/navigation/navigation-basics.html#forcing-a-modal-or-non-modal-navigation ).

    If I've previously navigated to "/Index/NavigationPage/ViewA" and I try to do a relative navigation to "ViewC", nothing happens. Seems like I need to preface every ContentPage with a NavigationPage, except when deeplinking.

  • JacobEgnerJacobEgner Member ✭✭
    edited May 14

    @BrianLagunas, thank you for your work on Prism and your answers to my questions (and so many other people's questions).

    @BrianLagunas said:
    Simply put, when you are navigating form a MDP, you are replacing the MDP.Detail. You aren't actually pushing anything onto a nav stack for the MDP.

    It seems you are saying that as long as a MDP is in the navigation stack, navigation will be "not the normal way" and mostly swap out the MDP.Detail, but it seems that also modal navigation might happen (see third picture in repo README.md, "/Index/Navigation/ViewA/Navigation?useModalNavigation=true/ViewB"). Do you agree with my statement about modal navigation?

    We have a hobby group at work, and we were messing around with HamburgerMenu as part of learning Xamarin.Forms+Prism, and we really liked how it used a MDP with no detail so that you could easily navigate around and every page (wrapped with a NavigationPage) could have access to the menu living in MDP.Master, but now that strategy seems to have downsides.

    Is there better way to have NavigationPage-wrapped-ContentPages have a hamburger button that causes a menu page to slide out?

    1. You may have found a bug in `GetNavigationPathUri()``, it should list the MDP in the nav stack too. Technically a NavPage isn't a separate page on the nav stack, it wraps the existing page, so Xamarin will not show it.

    Should I make a bug report at github.com/PrismLibrary/Prism/issues ?

    1. GetNavigationUriPath() provides the entire absolute navigation stack that Prism would use to create the current navigation stack. It will never match the objects in the Xamarin nav stacks. As mentioned above, the previous example may have a bug.

    Ok, thanks.

    1. You can't have a NavigationPage inside another NavigationPage. So when you are already in a NavigationPage and then navigate to another NavPage, it must be modal and Prism will force that.

    Ok, thanks. With MDP-rooted stuff, it seems like every navigation to a ContentPage needed another NavigationPage preface; I look forward to doing navigation experiments without the MDP root and seeing the behavior.

  • JacobEgnerJacobEgner Member ✭✭
    edited May 14

    Weird, I wrote a response to your wonderful answer (thanks, Brian!), and I even got a badge for it, but now it seems to have disappeared. I will write it again if I can't get the comment recovered.

    The forum people have recovered my prior comment, saying "Looks like it got marked as spam for some reason. You are good to go now".

  • BrianLagunasBrianLagunas USInsider ✭✭✭✭

    It seems you are saying that as long as a MDP is in the navigation stack, navigation will be "not the normal way" and mostly swap out the MDP.Detail, but it seems that also modal navigation might happen (see third picture in repo README.md, "/Index/Navigation/ViewA/Navigation?useModalNavigation=true/ViewB"). Do you agree with my statement about modal navigation?

    Yes, you can push a new page modally on the nav stack.

    We have a hobby group at work, and we were messing around with HamburgerMenu as part of learning Xamarin.Forms+Prism, and we really liked how it used a MDP with no detail so that you could easily navigate around and every page (wrapped with a NavigationPage) could have access to the menu living in MDP.Master, but now that strategy seems to have downsides.

    This is not what is actually happening. While you don't define the Detail in XAML, Prism is creating the Detail for you. Any time you use MDP, you are going to be updating the Detail page if you want to keep you MDP features such as the hamburger menu.

    Is there better way to have NavigationPage-wrapped-ContentPages have a hamburger button that causes a menu page to slide out?

    No, that is what a MDP is for.

    Should I make a bug report at github.com/PrismLibrary/Prism/issues ?

    Yes, but you must provide a sample app the reproduces the issue.

    It's important you fully understand how navigation works in Xamarin.Forms before trying to use Prism to navigation or else you will not predict, or understand, how navigation is actually happening.

  • JacobEgnerJacobEgner Member ✭✭

    Thanks again for your prompt and helpful answers.

    we really liked how it used a MDP with no detail

    This is not what is actually happening. While you don't define the Detail in XAML, Prism is creating the Detail for you.

    I apologize for my words being sloppy; you are saying what I meant. "MDP with no detail" defined in the XAML; navigation does the job of assigning a Detail page.

    No, that is what a MDP is for.

    Ok, thanks. Also yeah, we had some discussions where if we want a bunch of pages to have a hamburger icon to access the hamburger menu, then that kind of interferes with the natural place for the back icon, and maybe we are being silly in imagining an app where the nav stack is rooted with a MDP and has more than just "/MDP/NavigationPage/SomeDetailPage".

    Yes, but you must provide a sample app the reproduces the issue.

    Ok, how would HamburgerMenuMystery have to change to meet your requirements? Boil it down to the simplest possible app that still has the MasterDetailPage erroneously absent from GetNavigationUriPath?

    It's important you fully understand how navigation works in Xamarin.Forms before trying to use Prism to navigation or else you will not predict, or understand, how navigation is actually happening.

    Agree 100%. It's unfortunate that we didn't know that MDP changes the nature of navigation so much. There was a lot of stuff we read that helped us build a mental model of navigation, but then HamburgerMenu behavior contradicted a lot of what we predicted and made us question everything. I imagine another navigation-experiment-project that does not use MDP will match our old mental models better.

    Before our hobby group started messing with HamburgerMenu, and we stumbled on the TBD page Working w/ MasterDetailPages, we thought, "oooh, I bet this page fleshed out would help us a lot", but really we were underselling it. I've tried to read all that I could about Prism and navigation, but I just wasn't seeing anything that could explain what we were seeing.

    I've submitted some pull requests to your doc before. I hope that I can be in a position to help out with that doc page in the future. Thanks again for all your work and generosity.

Sign In or Register to comment.