【问题标题】:How to remove a current page from stack navigation Xamarin Forms如何从堆栈导航 Xamarin Forms 中删除当前页面
【发布时间】:2017-01-16 12:56:00
【问题描述】:

我正在努力做某事,但我无法解决这个问题。我有三个页面,一个是 MainPage、LoginUpPage 和 SignUpPage,在 LoginUpPage 内部有一个导航到 SignUpPage 的按钮,我想要做的是当我完成我的逻辑导航到另一个页面 CreatedPage 时,其中包含一个带有消息的标签 -成功,然后在 2 秒后返回到 LoginPage,问题是如果我从设备按下后退按钮,它将返回到带有消息标签的最后一页,我不希望那样。我有一个带有 BackButton 的工具栏,可以返回到我导航的每个页面。到目前为止,我有这个:

登录页面到注册页面:

Navigation.PushAsync(new SignupPage());

SignUpPage 到 CreatedPage :

await Navigation.PushModalAsync(new Created());

在我的 Contructor 的 CreatedPage 内部,这个方法:

    public async void Redirect()
    {
        await Task.Delay(TimeSpan.FromSeconds(2));
        await Navigation.PushAsync(new LoginPage());
    }

我知道question 基本上有三种方法可以导航到另一个页面:

Navigation.PushAsync(new OtherPage()); // to show OtherPage and be able to go back

Navigation.PushAsyncModal(new AnotherPage());// to show AnotherPage and not have a Back button

Navigation.PopAsync();// to go back one step on the navigation stack

在同一个问题中,有一个示例如何从堆栈中删除页面,但它不起作用。

item.Tapped += async (sender, e) => {
await Navigation.PushAsync (new SecondPage ());
Navigation.RemovePage(this);

};

【问题讨论】:

标签: c# xamarin.forms


【解决方案1】:

来回点击页面的次数,页面被添加到导航堆栈。根据点击次数,同一页面可能会多次出现在导航堆栈中。

如果导航堆栈上有两个或页面。

for (int PageIndex = Navigation.NavigationStack.Count; PageIndex >= 0; PageIndex--)
{  
    Navigation.RemovePage(Navigation.NavigationStack[PageIndex]);
}

这将删除导航堆栈中的所有页面,不包括主页(或导航堆栈顶部的页面)

如果用户在导航堆栈中留下了两个页面,并希望将导航堆栈中的第二页作为主页 (Navigationstack[1]) 并删除第一页 (Navigationstack[0]) ,它的工作原理如下

if (Navigation.NavigationStack.Count == 2)
{
    App.Current.MainPage.Navigation.RemovePage(Navigation.NavigationStack.First());
}

【讨论】:

    【解决方案2】:

    在这种情况下,您需要设置一个 Root 页面:

    //Master Detail Page
    
      public class RootPage : MasterDetailPage
        {
            MenuPage menuPage;
    
            public RootPage()
            {
                menuPage = new MenuPage(this);
                Master = menuPage;
                Detail = new NavigationPage(new HomePage());
            }
        }
    

    //Set the Root Page
    public class App : Application
    {
        public App()
        {
           InitializeComponent ();
    
           if(NewUser || NotLoggedIn)
              {
                 MainPage = new LoginPage();
              }
           else
              {
                 MainPage = new RootPage();
              }
        }
    }
    
    public class LoginPage : ContentPage
        {            
            private void SignupButtonOnClicked(object sender, EventArgs eventArgs)
            {
                Navigation.PushAsync(new SignupPage());
            }
        }
    
    
    public class SignupPage : ContentPage
        {            
            private void CreatedButtonOnClicked(object sender, EventArgs eventArgs)
            {
                Navigation.PushModalAsync(new CreatedPage());
            }
        }
    
    // Set the Login Page
    
    public class CreatedPage : ContentPage
        {
    
            private void CreatedButtonOnClicked(object sender, EventArgs eventArgs)
            {
                Navigation.PushModalAsync(new LoginPage());
    
                //Special Handel for Android Back button
                if (Device.OS == TargetPlatform.Android)
                Application.Current.MainPage = new LoginPage();
            }
    
        }
    

    这样后退按钮将不会返回上一页,因为它会将导航堆栈重置为根页面,即您的登录页面。

    【讨论】:

    • 这里有两个问题,第一个是在我的应用程序中我有这个InitializeComponent(); MainPage = new NavigationPage(new MenuPage()); 我需要将方法public App() 更改为public static page?我试着添加了await Navigation.PopToRootAsync();,我得到了一个异常=System.InvalidOperationException: PopToRootAsync is not supported globally on Android, please use a NavigationPage.
    • 我已经更新了代码,尝试实现更新后的代码。还要处理您在登录后重定向到 MenuPage 的登录凭据。
    • 我的 rootPage 我有这个 MainPage = new NavigationPage(new MenuPage()); MenuPage 有一个 MasterDetailPage whitch 包含一个 <local:MainPage/> MainPage 有一个菜单列表。我无法直接启动应用程序到 LoginPage 必须在 MenuPage 中启动。
    • 我得到了同样的异常PopToRootAsync is not supported globally on Android, please use a NavigationPage
    • android 需要一个条件 我已经更新了代码,请尝试实现。
    【解决方案3】:

    我之前没有尝试过,但您可以尝试以下解决方案:

    检索您的导航堆栈作为列表:

    var existingPages = Navigation.NavigationStack.ToList();
    

    然后删除你想要的页面

    然后将您的导航堆栈设置为修改后的列表

    【讨论】:

    • Navigation.NavigationStack.ToList() 返回 null ?
    • 我不知道为什么它实际上返回 null,但请确保您访问的是预期的 Navigation 属性。例如,如果您创建了一个扩展 ContentPage 类的新类并尝试访问其 Navigation 属性,则此 Navigation 属性可能与视图的 Navigation 属性不同,因此请确保此属性相同与您的视图中使用的一样。
    【解决方案4】:

    App.Navigation.RemovePage(App.Navigation.NavigationStack.ElementAt(App.Navigation.NavigationStack.Count - 2));

    导航到下一页后将删除页面

    App.Navigation 在哪里

    公共静态 INavigation 导航 { get;放; }

    在应用类中

    【讨论】:

      【解决方案5】:

      我发现清除堆栈并在清除堆栈上打开新页面的最简单方法

      await Navigation.PushAsync(new UserJourneysTabPage()); //Push the page you want to push
                  var existingPages = Navigation.NavigationStack.ToList(); 
                  //get all the pages in the stack
                  foreach (var page in existingPages)
                  {
                          //Check they type of the page if its not the 
                          //same type as the newly created one remove it
                          if (page.GetType() == typeof(UserJourneysTabPage))
      
                          continue;
      
                      Navigation.RemovePage(page);
                  }
      

      注意:如果页面类型相同,这不会从导航堆栈中清除页面,但您始终可以添加一个属性来区分新创建的页面和旧页面

      【讨论】:

        【解决方案6】:

        我正在发布此解决方案,用于使用 linq 从导航堆栈中删除任何所需页面。

        这里作为一个例子,我将删除除当前活动页面之外的所有页面。

        var currentPage = Navigation.NavigationStack[Navigation.NavigationStack.Count - 1];
        var pageList = Navigation.NavigationStack.Where(y => y != currentPage).ToList();
        
        foreach(var page in pageList)
            Navigation.RemovePage(page);
        

        【讨论】:

          【解决方案7】:

          以下例程非常适合我:

          Using System.Linq;
          
          ......
          
          
          try
          
          {
          
           foreach (var item in Application.Current.MainPage.Navigation.NavigationStack.ToList()
          
          {
          
                 if (item.GetType().Name == "ClientsPage" || item.GetType().Name == "PagoPage")
          
          
                 {   
          
                     Application.Current.MainPage.Navigation.RemovePage(item);
          
          
                 }
            }
                   
          }
          catch() {
                  }
          

          【讨论】:

            猜你喜欢
            • 2017-12-18
            • 2020-12-07
            • 1970-01-01
            • 1970-01-01
            • 2016-03-09
            • 1970-01-01
            • 2013-04-21
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多