0

ユーザー入力を要求し、その入力に基づいて一連の画鋲を生成する Windows ストア アプリを作成しています。画鋲をタップすると、アプリはより詳細なページに移動します。

今私が抱えている問題は次のとおりです。私のページはすべて自動的に生成された LayoutAwarePage から継承されるため、SaveState と LoadState を使用して画鋲を保存し、ナビゲーションで消去されないようにすることができます。問題は、SaveState によって提供される Dictionary オブジェクトに保存するピンを取得できないことです。

私が得るエラーは「Value cannot be null」で、LayoutAwarePage.OnNavigatedFrom() の _pageKey 変数を参照していますが、なぜそれが起こっているのかわかりません。

LoadState で逆シリアル化できるように JSON 文字列にシリアル化しようとしましたが、文字列または UIelement のリストを使用して同じ結果が得られます。

これはすべて、SaveState、LayoutAwarePAge、および SuspensionManager がどのように機能するかを理解していないことが原因だと思います。ディクショナリは文字列とオブジェクトのみを要求しているため、私がしていたことはうまくいくと思いました。

私は LayoutAwarePage の他のメソッドを使用していないので、SaveState と LoadState を使用するよりも良い方法があれば、私はすべて耳にします。

これらは、私が試した SaveState の 2 つのバージョンです。

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値を null にすることはできません) は、に保存しているものとは実際には関係ありませんDictionaryOnNavigateFrom()例外は、次のメソッドでスローされる可能性が最も高いです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ことがわかります。_pageKeyOnNavigatedToLayoutAwarePage

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 に答える