5

Is there a best practice for handling tombstoning and back key properly?

As it is stated in the MSDN docu you should save transient data in the OnNavigatedFrom method. Ok, so the code for saving states when tombstoning is clear.

But now if you press the back key the OnNavigatedFrom method is also called and if you don't add extra checks, you will first save states into the dictionary and shortly after that the page will be destroyed. And so will the PhoneApplicationPage.State dictionary. So the saving code is completely wasted CPU, disk and battery time.

This is what I've done to prevent it:

    protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
    {
        // when navigating back
        if (e.NavigationMode == System.Windows.Navigation.NavigationMode.Back)
        {
            backKeyPressed = true;
        }
    }

    protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
    {
        if (backKeyPressed)
        {
            // Don't save states on back key!
            backKeyPressed = false;     // set it anyway
            return;
        }

        // Tombstoning
        // save objects
        this.SaveState("text", someText);
        ...
    }

As a reminder: OnNavigatingFrom will only be called when navigating away/back from the page but not when app gets tombstoned.

Side note: Shown code covers only pages that can only navigate back. Thats why I added backKeypressed to OnNavigatingFrom. You need extra checks if the page can navigate to another page.

  1. Is there a better way to do this for every page you create?
  2. Now do I really have to add the backKeyPressed variable and check on every page I create?
  3. Shouldn't the framework provide something for us developer so we don't have to worry much about this?

What are your thoughts about this?

EDIT:

Updated question the make it clearer.

Buju
  • 1,546
  • 3
  • 16
  • 27

2 Answers2

2

your approach of checking the direcetion of navigation in OnNavigatingFrom is indeed the recommended practice in order to avoid the unneccessary performance hit of saving state just before the page gets removed from the backstack.

There is one clarification I want to add to your sample code: You should check the 'NavigationMode' property in the 'NavigationCancelEventArgs' to determine whether it's a forward or backward navigation.

Then only save the state in OnNavigatedFrom if it was a forward navigation, as your sample shows. This will help improve your performance when the user navigates backwards.

btlog
  • 4,760
  • 2
  • 29
  • 38
Stefan Wick MSFT
  • 13,600
  • 1
  • 32
  • 51
  • Thanks for the hint with NavigationMode. It would be nice if this behavior will be simplified in the future. Something like: add NavigationMode to OnNavigatedFrom or an own new method for tombstoning or something like that. So we won't have to use a separate backKeyPressed variable. – Buju Apr 06 '11 at 14:25
  • Yep, that's on the To-Do list :-) – Stefan Wick MSFT Apr 06 '11 at 14:27
1

Everything you ever needed to know about tombstoning is covered in Jeff Prorise's 4-part Real-World Tombstoning in Silverlight for Windows Phone 7 blog post series. You may want to pay particular attention to part 2 where Jeff talks about clearing up state when the application quits.

Derek Lakin
  • 16,179
  • 36
  • 51
  • thanks for the tip for using IsolatedStorage for tombstoning. Still it didn't properly answer the case for handling of tombstoning + back key on every page you create. If you are in OnNavigatedFrom, you have to support 3 cases: navigating back, tombstoning and navigating to another page. – Buju Apr 05 '11 at 14:05
  • Well, you're only storing the same set of values, so you're not going to fill up the state service, plus the only time you need to do anything is in OnNavigatedFrom, so won't be a problem to store your transient state at that point regardless. If perf becomes an issue then you're storing the wrong stuff at the wrong time and in the wrong place :) – Derek Lakin Apr 05 '11 at 14:08
  • 1
    +1: The way I look at it, the `PhoneApplicationPage.State` Dictionary should only be used for saving things like how far down a ListBox the user had scrolled, or which PivotItem was active. Computation intensive stuff like saving persistent view model data should be done in `Application.Deactivated` event. – Praetorian Apr 05 '11 at 15:51
  • I think you only get 10 seconds or so to complete your code to persist data in Application.Deactivated though? – Carlos P Nov 22 '12 at 16:45