Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 i navigate to another page, and then press "BACK" button, it closes the application. It does not remember the navigation history. The master detail page is as below:

 public class RootPage : MasterDetailPage
    {
        public RootPage ()
        {
            var menuPage = new MenuPage ();

            menuPage.Menu.ItemSelected += (sender, e) => NavigateTo (e.SelectedItem as MenuItem);

            Master = menuPage;
            Detail = new NavigationPage (new ContractsPage ());
        }

        void NavigateTo (MenuItem menu)
        {
            Page displayPage = (Page)Activator.CreateInstance (menu.TargetType);
            Detail =    new NavigationPage (displayPage);
            IsPresented = false;
        }
    }

so any ideas how to overcome this problem?

like image 698
SoftSan Avatar asked Jan 08 '15 09:01

SoftSan


2 Answers

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.

like image 119
PlasmaEye Avatar answered Nov 03 '22 09:11

PlasmaEye


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());
}
like image 41
Sten Petrov Avatar answered Nov 03 '22 07:11

Sten Petrov