【问题标题】:WinRT - How to ignore or delete page from navigation historyWinRT - 如何从导航历史记录中忽略或删除页面
【发布时间】:2012-10-03 16:14:26
【问题描述】:

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

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

所以我有这个:

Home Page - > Login Page - > Shopping Cart

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

我的问题是如何做到这一点,以及如何在 WinRT 上操作框架导航堆栈。我尝试了两次返回,但没有成功。

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

【问题讨论】:

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


    【解决方案1】:

    你可以用不同的方式来处理它。您可以使后退按钮多次导航,直到它到达主页或跳过登录页面。您还可以使登录页面显示在导航 Frame 之外 - 无论是在弹出窗口中还是在应用程序的不同层中。

    *更新

    在 8.1 中,平台在 Frame 上引入了 BackStackForwardStack 属性,您可以对其进行操作。

    【讨论】:

      【解决方案2】:

      我知道它很旧,但由于 Google 为我找到了这个页面,也许其他人也会找到这个页面。

      答案虽然是有效的解决方法,但不能回答问题。

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

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

      【讨论】:

      • 我很幸运在目标页面使用 Frame.BackStack.Remove(Frame.BackStack.Last())(例如本例中的购物车)。
      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • Frame 中没有 GoHome 方法。我错过了什么吗?
        • @AleksandarToplek 我猜微软已经改变了 Win 8.1 中的 api,它在 2 年前被问到问题时确实存在。
        • 哦,这很奇怪。整个导航框架在我看来是不完整的。我最终实现了自定义历史堆栈。
        • @AleksandarToplek 很酷,您应该将其发布为答案,以便其他人也可以使用它。
        【解决方案5】:

        我编写了自己的历史跟踪导航服务。你可以找到它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);
                    }
                }
            }
        }
        

        【讨论】:

          【解决方案6】:

          从堆栈中弹出:

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

          【讨论】:

          • NavigationService 在 winrt 中不存在
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-22
          • 2020-03-22
          • 2019-08-06
          • 2017-11-02
          相关资源
          最近更新 更多