在创建Windows 8应用程序时保存页面之间的状态

本文关键字:之间 状态 保存 创建 Windows 应用程序 | 更新日期: 2023-09-27 18:10:04

我一直在使用微软提供的c#或Visual Basic教程创建您的第一个Windows Store应用程序,但我在页面之间导航时遇到一些保存状态的问题。

使用c#或Visual Basic创建你的第一个Windows Store应用程序

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

我注意到当导航到的时候页面总是空的。什么好主意吗?

在创建Windows 8应用程序时保存页面之间的状态

启用 NavigationCacheMode 属性并添加 NavigationCacheMode="Enabled"

我也做了这个教程,我发现了一个跨页面导航保存状态的解决方案。

首先,重写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;
        }
    }
}

问题来自于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中保存状态的所有代码。当Page设置其NavigationCacheMode时,Frame class会为您完成此操作。