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; 
    }
}

我注意到导航到时页面状态始终为空。有任何想法吗?

4

3 回答 3

5

启用NavigationCacheMode页面的属性并添加NavigationCacheMode="Enabled"

或者

通过属性面板启用它。

于 2014-04-10T07:41:25.547 回答
3

我也完成了本教程,并找到了一种跨页面导航保存状态的解决方案。

首先,覆盖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  
        }
    }
}

事实上,我编写了另一个函数来检索图像,因此它可以在LoadStateOnNavigatedTo方法中使用。

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默认情况下会创建Page. 见Frame班级备注。所以LoadState事件处理程序总是用一个空状态参数调用

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

现在,如果您非常仔细地查看PhotoPage.xaml的完整代码,您会注意到在页眉中是NavigationCacheMode="Enabled"它的PhotoPage工作原理。

不需要所有关于在Page. 当设置它Frame class的.PageNavigationCacheMode

于 2014-03-02T08:44:10.467 回答