Xamarin.Forms – 主/详细页面和导航历史记录问题

我有一个使用masterdetail页面在所有页面显示菜单的应用程序。 导航在我的应用程序中以两种方式发生。 一个来自菜单,另一个来自仪表板。 因此,如果我导航到另一个页面,然后按“返回”按钮,它将关闭该应用程序。 它不记得导航历史记录。 主详细信息页面如下:

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; } } 

所以任何想法如何克服这个问题?

就像@ Sten-Petrov所说:你正在取代细节页面而不是触发历史机制。 要触发历史记录机制,您需要在Detail页面的Navigation属性上执行PushAsync(Page)。

在您的示例中,更改NavigateTo:

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

这不会取代内容,但会打开一个带有所需后退按钮function的新页面。

如果你想要使用Master-Detail页面的后退按钮function,那么你需要自定义后台堆栈过程,在我看来,这是不值得的。 在这种情况下,只需移动到不同的页面/导航结构。

这里的问题是您没有使用导航堆栈来执行页面的转换,而是替换您自己页面上的项目,因此除了导航到您的MasterDetailPage的页面之外,没有导航历史记录可以“返回”。

您可以通过创建一个inheritanceMasterDetailPage并初始化菜单的新MenuMasterDetail.cs类来解决此问题,然后创建从您的公共基础inheritance的MenuItem_A_Page.xaml(或.cs),并在您将使用Navigation.PushAsync(...)公共基类中Navigation.PushAsync(...)在页面之间转换。

基类:

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

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"}, } } } 

XAML中的子类(以及上面的CS,减去设置Detail的部分):

   ... 

同时更新您的App.cs以返回包含您拥有的第一个主/详细页面的导航页面(不是基本页面):

App.cs:

 public static Page GetMainPage () { return new NavigationPage(new FirstDetailWithMenuPage()); } 

我遇到了同样的问题, Detail.Navigation.PushAsync(itemSelected)使汉堡包菜单消失 ,同时创建另一个子类来保留代码和性能方面的大量工作。 所以,我决定将自己的堆栈数据类型用于Master详细信息页面。 保持跟踪和代码但工作正常有点棘手。

使用当前详细信息页面在应用程序加载时初始化它,并为选中的每个项目在堆栈顶部推送新页面。

 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); } } 

在同一页面代码后面覆盖OnBackButtonPressed()

  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(); } }