WinRT – 如何忽略或删除导航历史记录中的页面

我在WinRT metro(c# – xaml)应用程序中有以下情况:

用户启动应用程序并且他或她没有登录。在菜单栏中,我有一个按钮,可以将它们导航到购物车。 重要的是要提到他们无论登录/退出状态如何都可以点击它。

所以我有这个:

Home Page - > Login Page - > Shopping Cart 

一切都很好,但当我尝试按下购物车页面上的“返回”按钮时,我会导航回登录页面,这很有意义,因为页面在我的导航历史记录中。 但我不希望这样,我想将用户返回主页并跳过登录页面。

我的问题是如何做到这一点,以及如何在WinRT上操作帧导航堆栈。 我试着回去两次,但没有运气。

顺便说一句,我的页面是“LayoutAwarePage”页面,我正在使用与此http://dotnetbyexample.blogspot.com/2012/06/navigationservice-for-winrt.html类似的NavigationService。

你可以用不同的方式来接近它。 您可以将其设置为使后退按钮多次导航,直到它到达主页或跳过登录页面。 您还可以在登录页面中显示导航Frame外部的内容 – 在弹出窗口或应用程序的其他图层中。

*更新

在8.1中,平台在Frame上引入了BackStackForwardStack属性,您可以操作它们。

我知道它已经过时了,但是由于Google为我找到了这个页面,也许其他人也会找到这个页面。

答案虽然是有效的解决方法,但却没有回答这个问题。

您可以在登录页面上使用它,将其从后台堆栈中删除。

 if(login_was_successful == true) { this.Frame.Navigate(typeof(ShoppingCard)); if(this.Frame.CanGoBack) { this.Frame.BackStack.RemoveAt(0); } } 

项目的Common文件夹中有一个LayoutAwarePage.cs文件。 您可以从此文件更改后退按钮行为。

  protected virtual void GoBack(object sender, RoutedEventArgs e) { while (this.Frame.CanGoBack) this.Frame.GoBack(); // Use the navigation frame to return to the previous page //if (this.Frame != null && this.Frame.CanGoBack) this.Frame.GoBack(); } 

您可以在Back按钮事件上调用GoHome() ,它将带您进入HomePage或应用程序的第一页。

我写了自己的历史跟踪导航服务。 你可以在这里找到它。

如果我移动文件或删除它,这里是当前版本:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media.Animation; using Windows.UI.Xaml.Navigation; using MetroLog; using SparkiyClient.UILogic.Services; namespace SparkiyClient.Services { public class NavigationService : INavigationService { private static readonly ILogger Log = LogManagerFactory.DefaultLogManager.GetLogger(); private readonly Dictionary pagesByKey = new Dictionary(); private readonly Stack historyStack = new Stack(); private PageStackEntry currentPage; public string CurrentPageKey { get; private set; } public bool CanGoBack => this.historyStack.Any(); private static Frame GetFrame() { return (Frame)Window.Current.Content; } public void GoBack() { if (!this.CanGoBack) return; var item = this.historyStack.Pop(); this.NavigateTo(item.SourcePageType.Name, item.Parameter, false); } public void GoHome() { if (!this.CanGoBack) return; var item = this.historyStack.Last(); this.NavigateTo(item.SourcePageType.Name, item.Parameter, false); this.historyStack.Clear(); } public void NavigateTo(string pageKey, bool addSelfToStack = true) { this.NavigateTo(pageKey, null, addSelfToStack); } public void NavigateTo(bool addToStack = true) { this.NavigateTo(null, addToStack); } public void NavigateTo(object parameter, bool addSelfToStack = true) { this.NavigateTo(typeof(T).Name, parameter, addSelfToStack); } public void NavigateTo(string pageKey, object parameter, bool addToStack = true) { var lockTaken = false; Dictionary dictionary = null; try { Monitor.Enter(dictionary = this.pagesByKey, ref lockTaken); if (!this.pagesByKey.ContainsKey(pageKey)) throw new ArgumentException(string.Format("No such page: {0}. Did you forget to call NavigationService.Configure?", pageKey), "pageKey"); if (addToStack && this.currentPage != null) this.historyStack.Push(this.currentPage); GetFrame().Navigate(this.pagesByKey[pageKey], parameter); this.CurrentPageKey = pageKey; this.currentPage = new PageStackEntry(this.pagesByKey[pageKey], parameter, null); Log.Debug(this.historyStack.Reverse().Aggregate("null", (s, entry) => s + " > " + entry.SourcePageType.Name)); } finally { if (lockTaken && dictionary != null) Monitor.Exit(dictionary); } } public void Configure(string key, Type pageType) { var lockTaken = false; Dictionary dictionary = null; try { Monitor.Enter(dictionary = this.pagesByKey, ref lockTaken); if (this.pagesByKey.ContainsKey(key)) this.pagesByKey[key] = pageType; else this.pagesByKey.Add(key, pageType); } finally { if (lockTaken && dictionary != null) Monitor.Exit(dictionary); } } } } 

加载页面时使用

 this.NavigationCacheMode = NavigationCacheMode.Disabled; 

从堆栈弹出:

 NavigationService.RemoveBackEntry(); 

要触摸后退按钮导航到主菜单:

 protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e) { NavigationService. Navigate (new Uri ("/Main Page. xaml", UriKind.Relative)); } 

即使用户触摸后退按钮,也要将用户保留在主菜单中:

 protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e) { // cancel the navigation e.Cancel = true; }