Xamarin.Forms - Master/detail page and navigation history issue

后端 未结 3 539
抹茶落季
抹茶落季 2020-12-31 12:50

I have an app which uses masterdetail page to show menu in all page. The navigation is happened in two way in my app. one from the menu and second way from Dashboard. so if

相关标签:
3条回答
  • 2020-12-31 13:11

    Like what @Sten-Petrov said: you are replacing the detail page and not triggering the history mechanism. To trigger the history mechanism you will need to do a PushAsync(Page) on the Navigation property of the Detail page.

    In your example, change NavigateTo:

     void NavigateTo (MenuItem menu)
     {
         Page displayPage = (Page)Activator.CreateInstance (menu.TargetType);
         Detail.Navigation.PushAsync(displayPage);
     }
    

    This will not replace the content but will bring up a new page with the back button functionality you want.

    If you want back button functionality with the Master-Detail page then you'll need to customize the back stack process which, in my opinion, is not worth it. Just move to a different page/navigation structure in that case.

    0 讨论(0)
  • 2020-12-31 13:25

    The issue here is you're not using the Navigation stack to perform transitions of your pages but instead replace an item on your own page, so there's no navigation history to go "back" other than the page that navigated to your MasterDetailPage.

    You can resolve the problem by creating a new MenuMasterDetail.cs class that inherits MasterDetailPage and initializes a menu, then create MenuItem_A_Page.xaml (or .cs) that inherit from your common base and in your common base class you'll use Navigation.PushAsync(...) to transition between pages.

    base class:

    public class MenuDetailPage: MasterDetailPage{
      public MenuDetailPage(): base(){
        this.Master = BuildMyMenuListHere(); // the menu items will also define navigation targets
      }
    }
    

    subclass in CS:

    public class FirstDetailWithMenuPage: MenuDetailPage{
      public FirstDetailWithMenuPage()
        : base() // this creates the menu
      {
        this.Detail = new StackLayout{  // change this however you need
          Children = {
            new Label { Text = "This is the first page" },
            new Button { Text= "Ok"},
         }
      }
    }
    

    Subclass in XAML (along with the CS from above, minus the part where the Detail is set):

    <local:FirstDetailWithMenuPage namespace:YourNamespace;assembly=YourAssemblyName" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:local="clr-n xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="FirstDetailWithMenuPage">
        <local:FirstDetailWithMenuPage.Detail>
    ...
    

    Also update your App.cs to return a navigation page with the first master/detail page you have (not the base one):

    App.cs:

    public static Page GetMainPage ()
    {
      return new NavigationPage(new FirstDetailWithMenuPage());
    }
    
    0 讨论(0)
  • 2020-12-31 13:31

    I was having same issue, Detail.Navigation.PushAsync(itemSelected) makes hamburger menu vanish and also creating another sub-class to retain seemed big work on code and performance. So, I decided to use my own stack datatype for Master detail page. It was bit tricky to keep track and code but working fine.

    Initialize it at the app load with current Detail page and for each item selected Push new page on top of stack.

    public partial class MyMasterDetailPage: MasterDetailPage
        {
            private Stack navigationStack = new Stack();
            public MyMasterDetailPage()
            {
                InitializeComponent();
                navigationStack.Push(Detail);
                try
                {
                    masterPage.listView.ItemSelected += OnItemSelected;
    
                }
                catch (Exception exc)
                {
    
                    System.Diagnostics.Debug.WriteLine(exc.Message);
                }
    
            }
    

    Override OnBackButtonPressed() in same Page code behind

            protected override bool OnBackButtonPressed()
            {
                try
                {
                    var lastPage = navigationStack.Pop();
                    if (lastPage.Equals(Detail))
                        lastPage = navigationStack.Pop();
    
                    Detail = (Page)lastPage;
                    IsPresented = false;
    
                   // to avoid app close when complete pop and new page is push on top of it 
                    if (navigationStack.Count == 0) 
                        navigationStack.Push(Detail);
                    return true;
                }
                catch (Exception)
                {
    
                    return base.OnBackButtonPressed();
                }
            }
    
    0 讨论(0)
提交回复
热议问题