Saving state between pages when creating a Windows 8 application

I'm following the creation of my first Windows Store app with C # or Visual Basic tutorials provided by Microsoft, but I have problems maintaining state when navigating between pages.

Build your first Windows Store app with C # or Visual Basic

Part 3: Navigation, Layout, and Views

Basically, I noticed that if I go from the main page to the photo page, select a photo, go to the main page and go to the photo page again, it does not remember the selected photo. I use the following code to go to the page from the main page.

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

On the photos page, loadstate method

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

Page Save Status

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

I noticed that pagestate is always oriented when navigating. Any ideas?

+4
source share
3 answers

I also did this tutorial, and I found one solution to save state in page navigation.

First, override OnNavigatedFrom to save the file token in State Frame:

 protected override void OnNavigatedFrom(NavigationEventArgs e) { base.OnNavigatedFrom(e); var state = SuspensionManager.SessionStateForFrame(this.Frame); state["mruToken"] = mruToken; } 

Cancel OnNavigatedTo to load the token from state:

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

In fact, I wrote another function to extract the image so that it can be used in both LoadState and OnNavigatedTo methods .

 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
source

Enable the NavigationCacheMode property of the page and add NavigationCacheMode="Enabled"

OR

Enable its property bar.

+5
source

The problem comes from the NavigationHelper OnNavigateTo method

 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) , if always true, because Frame creates a new instance of Page by default. See Frame Class Notes . Thus, the LoadState event handler is always called with the zero state parameter

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

Now, if you look at the full PhotoPage.xaml code, you will notice that there is this NavigationCacheMode="Enabled" in the page header that is what PhotoPage .

It is not necessary that all codes store states in Page . Frame class does this for you when Page sets its NavigationCacheMode .

0
source

All Articles