Navigation Not Working Properly When Using Prism Deep-linking What Am I Doing Wrong?

JoepJoep USUniversity

Hi,
I am trying to build some basic navigation in Xamarin Forms using Prism.
In the app.cs I use this navigation to make a MasterDetailPage with a NavigationPage and a “MainPage”.
NavigateAsync("MasterDetail/Navigation/MainPage");
This works fine.
Now I add some buttons tot the MasterDetailPage to Navigate to Page1 and Page2
Using this code in the MasterDetailViewModel
private void NavigatePage(string name)
{
_navigationService.NavigateAsync($"Navigation/MainPage/{name}");
}
Where name is Page1 or Page2 depending on the button pressed.
This works only when navigating from the MainPage.
When navigation from Page1 or Page2 I get redirected back to the Mainpage instead of Mainpage/Page1.
I am using this Mainpage as a dashboard thats why I want it in my navigation stack.
How can I make this work?

Best Answer

Answers

  • BrianLagunasBrianLagunas USInsider ✭✭✭

    The way you are trying to navigate from a MasterDetaiLPage does not make your intentions clear. If you could explain exactly what you are trying to achieve in a little more detail, maybe I can help give you better direction.

  • JoepJoep USUniversity

    Basically I’m trying to build a master-detail page navigation.

    In my detail page I want a standard page on the bottom of the stack which will function as a sort of “home” page to which all detail pages can navigate back to without interacting with the master page.

    I uploaded a project op GitHub with the implemented navigation.
    https://github.com/JoepdeKok/ExampleRepo

  • BrianLagunasBrianLagunas USInsider ✭✭✭

    Now I see what you are trying to do. In fact, you found a bug in Xamarin.Forms navigation. This can easily be reproduced with the following code. Run this app and you will get the exact same behavior. It seems that the NavigationPage does not properly set the CurrentPage property. So instead of the CurrentPage being ViewA or ViewB, the MainPage is set as the CurrentPage even though it is at index 0 of the NavigationStack.

        public class App : Application
        {
            public App()
            {
                MainPage = new MainMasterDetailPage();
            }
        }
    
        public class MainMasterDetailPage : MasterDetailPage
        {
            NavigationPage _navPage;
    
            public MainMasterDetailPage()
            {
                Title = "Main";
    
                var btnViewA = new Button() { Text = "ViewA" };
                btnViewA.Clicked += Button_Clicked;
    
                var btnViewB = new Button() { Text = "ViewB" };
                btnViewB.Clicked += Button_Clicked;
    
                var stack = new StackLayout();
                stack.Children.Add(btnViewA);
                stack.Children.Add(btnViewB);
    
                var master = new ContentPage() { Title = "Master", Content = stack };
    
                _navPage = new NavigationPage(new OriginalRoot());
    
                Master = master;
                Detail = _navPage;
            }
    
            private async void Button_Clicked(object sender, EventArgs e)
            {
                Page newPage = null;
    
                var btn = (Button)sender;
                if (btn.Text == "ViewA")
                    newPage = new ViewA();
                else
                    newPage = new ViewB();
    
                //build our new navigation stack
                var newMainPage = new MainPage();
                await newMainPage.Navigation.PushAsync(newPage);
    
                //clear orginal stack if any
                await _navPage.Navigation.PopToRootAsync(false);
    
                //push new stack into the navigationPage
                await _navPage.Navigation.PushAsync(newMainPage);
    
                //remove the original navigation root instance
                var pageToRemove = _navPage.Navigation.NavigationStack[0];
                _navPage.Navigation.RemovePage(pageToRemove);
    
                //The CurrentPage is always MainPage
                //the currentPage should be either ViewA or ViewB, not MainPage.
                var currentPage = _navPage.CurrentPage;
    
                IsPresented = false;
            }
        }
    
        public class OriginalRoot : ContentPage
        {
            public OriginalRoot()
            {
                Title = "Root";
                Content = new Label() { Text = "Root" };
            }
        }
    
        public class MainPage : ContentPage
        {
            public MainPage()
            {
                Title = "MainPage";
                Content = new Label() { Text = "MainPage" };
            }
        }
    
        public class ViewA : ContentPage
        {
            public ViewA()
            {
                Title = "ViewA";
                Content = new Label() { Text = "View A" };
            }
        }
    
        public class ViewB : ContentPage
        {
            public ViewB()
            {
                Title = "ViewB";
                Content = new Label() { Text = "View B" };
            }
        }
    
  • BrianLagunasBrianLagunas USInsider ✭✭✭

    I went ahead and submitted this bug. The status can be tracked here:

    https://bugzilla.xamarin.com/show_bug.cgi?id=45978

  • JoepJoep USUniversity

    Thank you for the fast reply’s and workaround.
    I will implement this workaround in my code, "NavigationPage/MainPage/ViewA" are enough stages of deep-linking with what I try to do. I will also keep an eye on the bug report.
    Kind regards,
    Joep

Sign In or Register to comment.