Universal Windows App C# - 在导航到同一页面的新实例时缓存页面的实例(和状态)

Universal Windows App C# - Cache an instance (and state) of a page when navigating to a new instance of the same page

嗨,Whosebug 社区,

我正在使用 C# 和 XAML 为 Windows 开发一个通用应用程序。到目前为止,进展顺利(整个框架非常易于使用)但是我 运行 遇到了一个与页面导航和状态缓存相关的问题,我希望得到一些帮助。

在标准模板中,通过应用程序导航将如下所示: 主页 -> 个人资料 (ID 1) -> 游戏 (ID 120) -> (返回)个人资料 (ID 1) -> (返回)主页 -> 个人资料 (ID 2) -> 游戏 (ID 210)

但是,我想做这样的事情: 主页 -> 个人资料 (ID 1) -> 个人资料 (ID 2) -> 个人资料 (ID 3) -> 游戏 (ID 120)

此要求背后的原因很简单:个人资料页面包含该个人资料的朋友、群组、游戏等列表。点击一个朋友应该会把你带到他们的个人资料页面,从那里你应该能够查看他们的详细信息、他们的朋友等,并继续向下钻取朋友列表或群组(可以 link 回到个人资料)。

这很重要,因为我在 SO 上遇到的大多数问题都与此相关...但是 我已经能够像我一样正确地在列表中来回导航在第二个例子中列出。我遇到的问题来自导航期间的一些有趣的缓存和状态问题。

为简单起见,我们只讨论 Windows Phone 视图;配置文件页面包含一个具有四个部分(详细信息、游戏、好友、组)的数据透视表 Table。如果我在用户 1 的个人资料上,滑动到朋友部分,然后点击用户 2 的个人资料,然后导航发生,我的后台堆栈中有 3 个页面(主页,用户 1 的个人资料,用户的个人资料2).这不是我遇到麻烦的部分;我遇到的问题与向后导航有关 - 当我点击后退按钮并在框架上向后导航时,我返回到用户 1 的配置文件(这很好),但是视图的 状态被重置,而不是在 'Friends' 部分,我返回到第一部分 (在本例中是 'Details' 部分 - 从用户体验的角度来看这很烦人)。

我尝试过 NavigationHelper 和 SuspensionManager 并尝试将页面缓存设置为启用,但是我得到了一些意想不到的结果。如上所述,如果我没有将 NavigationCacheMode 设置为 Enabled,那么当我向后导航时,我总是会返回到第一个数据透视部分,但是如果我确实将缓存模式设置为 Enabled,那么当我导航到配置文件页面的新实例时,然后状态似乎被回收,而不是出现在新配置文件的 'Details' 部分,我被加载到导航发生时所在的同一部分(即,如果我在 'Friends' 部分对于用户 1,然后当我点击用户 2 时,我将位于用户 2 的 'Friends' 部分。从用户体验的角度来看也很烦人)。当我向后导航时也会发生同样的情况,如果我是 4 个配置文件深度并查看配置文件 4 的 'Groups' 部分,当我返回时,我将查看组的配置文件部分3(即使我从 'Friends' 部分的配置文件 3 -> 配置文件 4 导航)

你们有没有遇到过这种情况?我不是在专门寻找代码片段(尽管我绝对没有拒绝它们的习惯!),而更多的是我应该如何处理这个问题的思考过程。我知道有些应用程序会做类似的事情,我确定我遗漏了一些小东西,但我们将不胜感激任何建议。

我正在尝试实现的此类导航的一个示例是在 Hulu 应用程序上。如果您 select 一个系列并滑动到 'Recommended' 部分,您将看到其他节目。点击这些节目之一将打开该节目的详细信息(您可以深入多层),但是点击后退按钮将带您回到您观看的最后一个系列(最重要的是,还会让您回到'Recommended' 部分)

通常我绝对会提供代码片段,但由于这是一个更宽泛的问题,而不是 "Why doesn't my code work?" 问题,我决定推迟,只有在需要时才会提供代码片段。

提前致谢!

页面缓存在 Windows 商店应用程序中变得更加灵活,但也更加复杂。您现在可以灵活地实现像您一样的导航模式,但您还必须手动做很多事情。

首先是 NavigationCache:您可以在页面上启用它(但只能在构造函数中启用)。 为了使缓存正常工作,您还必须设置 CacheSize(它是默认值 App.xaml.cs 并设置为 1。您必须增加它才能正常工作。

不过,它只在缓存中保留一个页面实例。在您的例子中,您使用不同的 ID 多次导航到该页面。启用导航缓存后,它只会确保所有内容都落在页面的同一实例上。

我通常只缓存我的应用程序的根页面,并且只有当它包含大量数据(比如你的中心)时才缓存。

NavigationCache 如果用于经常填满大量内存,因此您的应用程序在置于后台时会提前关闭。小心使用。

通常最好在每次导航到页面时重建页面并缓存数据(如果通过网络获取)。

NavigationHelper 提供了一个简单的标准实现来保存页面的状态字典。当您的页面在后退导航中重新创建时,您仍然需要手动处理它的状态。

它只是为您提供了一个字典,您可以在其中保存值:您所在的 HubSection、您滚动的距离等。

它利用 BackStackDepth 为您提供当前页面的正确词典。

取回字典后,您必须设置 HubSection、向下滚动等。

所以最后:是的,你必须手工完成所有这些...