简体   繁体   English

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

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

I have an app which uses masterdetail page to show menu in all page. 我有一个使用masterdetail页面在所有页面显示菜单的应用程序。 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 what @Sten-Petrov said: you are replacing the detail page and not triggering the history mechanism. 就像@ Sten-Petrov所说:你正在取代细节页面而不是触发历史机制。 To trigger the history mechanism you will need to do a PushAsync(Page) on the Navigation property of the Detail page. 要触发历史记录机制,您需要在Detail页面的Navigation属性上执行PushAsync(Page)。

In your example, change NavigateTo: 在您的示例中,更改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. 如果你想要使用Master-Detail页面的后退按钮功能,那么你需要自定义后台堆栈过程,在我看来,这是不值得的。 Just move to a different page/navigation structure in that case. 在这种情况下,只需移动到不同的页面/导航结构。

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. 这里的问题是你没有使用导航堆栈来执行页面的转换,而是替换你自己页面上的项目,因此除了导航到你的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. 您可以通过创建一个继承MasterDetailPage并初始化菜单的新MenuMasterDetail.cs类来解决此问题,然后创建从您的公共基础继承的MenuItem_A_Page.xaml(或.cs),并在您将使用Navigation.PushAsync(...)公共基类中Navigation.PushAsync(...)在页面之间转换。

base class: 基类:

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

subclass in CS: 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): XAML中的子类(以及上面的CS,减去设置Detail的部分):

<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以返回包含您拥有的第一个主/详细页面的导航页面(不是基本页面):

App.cs: App.cs:

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

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. 我遇到了同样的问题, Detail.Navigation.PushAsync(itemSelected)使汉堡包菜单消失 ,同时创建另一个子类来保留代码和性能方面的大量工作。 So, I decided to use my own stack datatype for Master detail page. 所以,我决定将自己的堆栈数据类型用于Master详细信息页面。 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 在后面的相同页面代码中覆盖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();
            }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM