【问题标题】:saving state between pages when creating a windows 8 app创建 Windows 8 应用程序时在页面之间保存状态
【发布时间】:2014-04-10 16:04:17
【问题描述】:

我一直在关注 Microsoft 提供的使用 C# 或 Visual Basic 创建您的第一个 Windows 应用商店应用教程,但是在页面之间导航时保​​存状态时遇到了一些问题。

Create your first Windows Store app using C# or Visual Basic

Part 3: Navigation, layout, and views

基本上我注意到,如果我从主页导航到照片页面选择一张照片,导航回主页然后再次转到照片页面,它不会记住所选的照片。我正在使用以下代码从主页导航到照片页面。

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

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

【问题讨论】:

  • 您是否验证了从 PhotoPage 导航时调用了 SaveState 并设置了 pageState?

标签: c# windows-store-apps


【解决方案1】:

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

通过属性面板启用它。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      问题来自 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 Class Remarks。所以LoadState事件处理程序总是用一个空状态参数调用

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

      现在,如果您仔细查看PhotoPage.xaml 的完整代码,您会注意到在页眉中有这个NavigationCacheMode="Enabled",这就是PhotoPage 起作用的原因。

      Page 中不需要所有关于保存状态的代码。当Page 设置它的NavigationCacheMode 时,Frame class 会为您执行此操作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-15
        相关资源
        最近更新 更多