【问题标题】:Windows Store apps, save and load the state of Bing Maps Pushpins on navigation between pagesWindows Store 应用程序,在页面之间导航时保​​存和加载 Bing Maps Pushpins 的状态
【发布时间】:2013-05-27 21:04:18
【问题描述】:

我正在制作一个要求用户输入的 Windows 应用商店应用程序,然后根据该输入生成一堆图钉。当点击图钉时,应用会导航到更详细的页面。

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

我得到的错误是“值不能为空”,它指的是 LayoutAwarePage.OnNavigatedFrom() 中的 _pageKey 变量,我不知道为什么会这样。

我尝试将它们序列化为 JSON 字符串,以便在 LoadState 中对其进行反序列化,但我使用字符串或 UIelement 列表得到相同的结果。

我认为这都是由于我对 SaveState、LayoutAwarePAge 和 SuspensionManager 的工作原理缺乏了解。我认为我正在做的事情会起作用,因为 Dictionary 只要求一个字符串和一个对象。

我没有使用 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;
    }

【问题讨论】:

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


    【解决方案1】:

    您遇到的错误(_pagekey 值不能为空)与您保存到 Dictionary 中的内容并没有真正的关系。异常很可能是在LayoutAwarePageOnNavigateFrom()方法中抛出的:

    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 的其余代码,您会发现_pageKey 的值是在LayoutAwarePageOnNavigatedTo 方法中设置的:

    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
    }
    

    这将确保基本实现将执行并设置_pageKey 值,并调用LoadState() 以加载先前保存的状态(如果有)。

    【讨论】:

    • 谢谢我知道是什么变量导致了错误以及在哪里,我只是没有意识到 OnNavigatedTo 已被覆盖。发生的事情是我将项目创建为空白页面,然后将其更改为继承表单 LayoutAwarePage 而不是 Page,因此 OnNavigatedTo 方法已经存在,未更改。
    • 我也有同样的问题。但我打电话给'base.OnNavigatedTo(e)'
    • @SaadAnees 您的_pageKey 值为null?好吧,如果您正在调用base.OnNavigatedTo,请尝试逐步执行该方法以确定为什么它的值将保持null
    • protected override void OnNavigatedFrom(NavigationEventArgs e) { var frameState = SuspensionManager.SessionStateForFrame(this.Frame); var pageState = new Dictionary&lt;String, Object&gt;(); this.SaveState(pageState); frameState[_pageKey] = pageState; }
    • @SaadAnees 那是 Windows 8.1 模板,代码来自 NavigationHelper.OnNavigatedFrom?在这种情况下,_pageKeyNavigationHelper.OnNavigatedTo 中初始化。它可能不是从您页面的OnNavigatedTo 调用的,因为它应该是。顺便说一句,这个讨论越来越需要一个单独的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-26
    • 1970-01-01
    相关资源
    最近更新 更多