How to save ListView and ScrollViewer family controls scroll position

One of the suggested guidelines when creating a Windows Phone application is that when the user quits an application, the states of the pages are saved, so that when the user re-opens the application, it feels like he never quit.

With the Mango update, it is now possible to save the states of application pages, providing there is enough memory. However, there will be some cases when the application will tombstone. The purpose of my utility static class StateManager will help to save a ListView/ScrollViewer scroll position or other controls that have an internal ScrollViewer.

Before explaining my utility class works, let’s see what happen when the scroll position is not saved:

1- Create a “Windows Phone Databound Application”.
2- Run the app then scroll the list to the last item.
3- Press the Start button.
4- Press the Back button.

The state is preserved. Great, but…

Now, stop debugging the application and go to the properties of the project. In the Debug section, check the option “Tombstone upon deactivation while debugging”. This is the only way to force the tombstoning process while debugging.

Tombstone

Execute the last 3 steps and you’ll see that the list scroll position is not saved.

To fix this issue, insert the StateManager class (provided at the end of the article) in your project and call StateManager.SaveScrollViewerOffset and StateManager.RestoreScrollViewer on the list that you want to save/restore scroll position. The best places to insert those calls are in the method OnNavigatedTo and OnNavigatedFrom.

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    StateManager.RestoreScrollViewerOffset(MainListBox);
    
}

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);

    StateManager.SaveScrollViewerOffset(MainListBox);
}

Download StateManager.cs
Download Sample project