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

时间:2012-10-03 16:14:27

标签: c# xaml navigation microsoft-metro windows-runtime

我的WinRT metro(c# - xaml)应用程序中存在以下情况:

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

所以我有这个:

Home Page - > Login Page - > Shopping Cart

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

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

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

7 个答案:

答案 0 :(得分:12)

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

*更新

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

答案 1 :(得分:9)

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

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

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

if(login_was_successful == true)
{
    this.Frame.Navigate(typeof(ShoppingCard));

    if(this.Frame.CanGoBack)
    {
        this.Frame.BackStack.RemoveAt(0);
    }
}

答案 2 :(得分:2)

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

答案 3 :(得分:0)

您可以在GoHome()按钮事件上致电Back,这会将您带到HomePage或应用程序的第一页。

答案 4 :(得分:0)

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

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

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<NavigationService>();
        private readonly Dictionary<string, Type> pagesByKey = new Dictionary<string, Type>();
        private readonly Stack<PageStackEntry> historyStack = new Stack<PageStackEntry>();
        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<T>(bool addToStack = true)
        {
            this.NavigateTo<T>(null, addToStack);
        }

        public void NavigateTo<T>(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<string, Type> 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<string, Type> 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);
            }
        }
    }
}

答案 5 :(得分:-2)

加载页面时使用

this.NavigationCacheMode = NavigationCacheMode.Disabled;

答案 6 :(得分:-3)

从堆栈弹出:

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