0

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

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

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

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

我认为这都是由于我对 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;
    }
4

1 回答 1

1

您得到的错误(_pagekey值不能为空)与您保存到Dictionary. 异常最有可能在以下OnNavigateFrom()方法中引发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您会发现在方法中_pageKey设置的值是:OnNavigatedToLayoutAwarePage

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()以加载先前保存的状态(如果有)。

于 2013-05-28T04:30:02.133 回答