4

Microsoft が提供する「C# または Visual Basic を使用して初めての Windows ストア アプリを作成する」チュートリアルに従っていますが、ページ間を移動するときに状態を保存するときに問題が発生します。

C# または Visual Basic を使用して最初の Windows ストア アプリを作成する

パート 3: ナビゲーション、レイアウト、ビュー

基本的に、メイン ページから写真ページに移動して写真を選択し、メイン ページに戻ってからもう一度写真ページに移動すると、選択した写真が記憶されていないことに気付きました。次のコードを使用して、メイン ページから写真ページに移動しています。

private void photoPageButton_Click(object sender, RoutedEventArgs e)
{
    this.Frame.Navigate(typeof(PhotoPage));
}

写真ページでは、loadstate メソッドは

protected async override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{
    if (pageState != null && pageState.ContainsKey("mruToken"))
    {
        object value = null;
        if (pageState.TryGetValue("mruToken", out value))
        {
            if (value != null)
            {
                mruToken = value.ToString();

                // Open the file via the token that you stored when adding this file into the MRU list.
                Windows.Storage.StorageFile file =
                    await Windows.Storage.AccessCache.StorageApplicationPermissions.MostRecentlyUsedList.GetFileAsync(mruToken);

                if (file != null)
                {
                    // Open a stream for the selected file.
                    Windows.Storage.Streams.IRandomAccessStream fileStream =
                        await file.OpenAsync(Windows.Storage.FileAccessMode.Read);

                    // Set the image source to a bitmap.
                    Windows.UI.Xaml.Media.Imaging.BitmapImage bitmapImage =
                        new Windows.UI.Xaml.Media.Imaging.BitmapImage();

                    bitmapImage.SetSource(fileStream);
                    displayImage.Source = bitmapImage;

                    // Set the data context for the page.
                    this.DataContext = file;
                }
            }
        }
    }
}

写真ページの保存状態は

protected override void SaveState(Dictionary<String, Object> pageState)
{
    if (!String.IsNullOrEmpty(mruToken))
    {
        pageState["mruToken"] = mruToken; 
    }
}

ナビゲートすると、pagestate が常に null になることに気付きました。何か案は?

4

3 に答える 3

3

私もこのチュートリアルを行ったところ、ページ ナビゲーション全体で状態を保存する 1 つの解決策が見つかりました。

まず、ファイル トークンを State Frame に保存するために OnNavigatedFromをオーバーライドします。

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);

    var state = SuspensionManager.SessionStateForFrame(this.Frame);
    state["mruToken"] = mruToken;
}

状態からトークンをロードするために 、 OnNavigatedToをオーバーライドします。

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    var state = SuspensionManager.SessionStateForFrame(this.Frame);
    if (state != null && state.ContainsKey("mruToken"))
    {
        object value = null;

        if (state.TryGetValue("mruToken", out value))
        {
           // the same code as LoadState to retrieve the image  
        }
    }
}

実際、画像を取得する別の関数を作成して、 LoadStateメソッドとOnNavigatedToメソッドの両方で使用できるようにしました。

private async void restoreImage(object value)
{
    if (value != null)
    {
        mruToken = value.ToString();

        // Open the file via the token that you stored when adding this file into the MRU list.
        Windows.Storage.StorageFile file =
            await Windows.Storage.AccessCache.StorageApplicationPermissions.MostRecentlyUsedList.GetFileAsync(mruToken);

        if (file != null)
        {
            // Open a stream for the selected file.
            Windows.Storage.Streams.IRandomAccessStream fileStream =
                await file.OpenAsync(Windows.Storage.FileAccessMode.Read);

            // Set the image source to a bitmap.
            Windows.UI.Xaml.Media.Imaging.BitmapImage bitmapImage =
                new Windows.UI.Xaml.Media.Imaging.BitmapImage();

            bitmapImage.SetSource(fileStream);
            displayImage.Source = bitmapImage;

            // Set the data context for the page.
            this.DataContext = file;
        }
    }
}
于 2013-06-11T01:27:38.337 に答える
0

問題は NavigationHelper OnNavigateTo メソッドから来ています

public void OnNavigatedTo(NavigationEventArgs e)
    {
        var frameState = SuspensionManager.SessionStateForFrame(this.Frame);
        this._pageKey = "Page-" + this.Frame.BackStackDepth;

        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
            if (this.LoadState != null)
            {
                this.LoadState(this, new LoadStateEventArgs(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
            if (this.LoadState != null)
            {
                this.LoadState(this, new LoadStateEventArgs(e.Parameter, (Dictionary<String, Object>)frameState[this._pageKey]));
            }
        }
    }

if (e.NavigationMode == NavigationMode.New)Frameデフォルトでは の新しいインスタンスを作成するため、常に true の場合PageFrameクラスの備考を参照してください。そのため、LoadStateイベント ハンドラは常に null 状態パラメータで呼び出されます

if (this.LoadState != null)
{
    this.LoadState(this, new LoadStateEventArgs(e.Parameter, null));
}

ここで、 PhotoPage.xamlの完全なコードをよく見ると、ページ ヘッダーにこれが機能NavigationCacheMode="Enabled"していることがわかりますPhotoPage

で状態を保存するためのコードは必要ありませんPageFrame classが をPage設定すると、がそれを行いますNavigationCacheMode

于 2014-03-02T08:44:10.467 に答える