Windows应用商店应用,在页面之间的导航上保存并加载Bing Maps Pushpins的状态

时间:2013-05-27 21:04:19

标签: windows-8 windows-runtime microsoft-metro windows-store-apps bing-maps

我正在创建一个Windows应用商店应用程序,询问用户输入,然后根据该输入生成一堆图钉。点击图钉后,应用会导航到包含更多详细信息的页面。

现在我遇到的问题是: 我的页面都继承自动生成的LayoutAwarePage,因此我可能会使用SaveState和LoadState来保存图钉,这样就不会在导航上擦除它们。问题是我无法将引脚保存到SaveState提供的Dictionary对象中。

我得到的错误是“Value not not null”,它指的是LayoutAwarePage.OnNavigatedFrom()中的_pageKey变量,我不知道它为什么会发生。

我已经尝试将它们序列化为JSON字符串,因此我可以在LoadState中对其进行反序列化,但是我使用字符串或UI元素列表得到相同的结果。

我认为这完全是由于我对SaveState,LayoutAwarePAge和SuspensionManager的工作方式缺乏了解。我认为我正在做的事情会起作用,因为字典只是要求一个字符串和一个对象。

我没有使用LayoutAwarePage中的任何其他方法,所以如果有比使用SaveState和LoadState更好的方法,我会全力以赴。

这是我尝试过的两个版本的SaveState:

使用JSON

    protected override void SaveState(Dictionary<String, Object> pageState)
    {
        List<string> pindata = new List<string>();
        List<string> serialisedpins = new List<string>();
        foreach (Pushpin ele in map.Children)
        {
            pindata = ele.Tag as List<string>;
            serialisedpins.Add(JsonConvert.SerializeObject(pindata));
        }

        string jasoned = JsonConvert.SerializeObject(serialisedpins);
        pageState["pins"] = jasoned;
    }

使用UIElement列表

    protected override void SaveState(Dictionary<String, Object> pageState)
    {
        List<UIElement> pins = new List<UIElement>(map.Children);
        pageState["pins"] = pins;
    }

1 个答案:

答案 0 :(得分:1)

您获得的错误(_pagekey值不能为空)与您保存到Dictionary的内容无关。 OnNavigateFrom()的{​​{1}}方法很可能会抛出异常:

LayoutAwarePage

如果您查看protected override void OnNavigatedFrom(NavigationEventArgs e) { var frameState = SuspensionManager.SessionStateForFrame(this.Frame); var pageState = new Dictionary<String, Object>(); this.SaveState(pageState); frameState[_pageKey] = pageState; // <-- throws exception because _pageKey is null } 代码的其余部分,您会发现LayoutAwarePage的{​​{1}}方法设置了_pageKey的价值:

OnNavigatedTo

通常原因是您在自己的页面中覆盖LayoutAwarePage而未在其中调用protected override void OnNavigatedTo(NavigationEventArgs e) { // Returning to a cached page through navigation shouldn't trigger state loading if (this._pageKey != null) return; var frameState = SuspensionManager.SessionStateForFrame(this.Frame); this._pageKey = "Page-" + this.Frame.BackStackDepth; <-- this line sets the _pageKey value if (e.NavigationMode == NavigationMode.New) { // Clear existing state for forward navigation when adding a new page to the // navigation stack var nextPageKey = this._pageKey; int nextPageIndex = this.Frame.BackStackDepth; while (frameState.Remove(nextPageKey)) { nextPageIndex++; nextPageKey = "Page-" + nextPageIndex; } // Pass the navigation parameter to the new page this.LoadState(e.Parameter, null); } else { // Pass the navigation parameter and preserved page state to the page, using // the same strategy for loading suspended state and recreating pages discarded // from cache this.LoadState(e.Parameter, (Dictionary<String, Object>)frameState[this._pageKey]); } } 。覆盖它的基本模式应该始终是:

OnNavigatedTo

这将确保基本实现将执行并设置base.OnNavigatedTo(e)值以及调用protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); // the rest of your own code } 以加载先前保存的状态(如果有的话)。