Saving Page State in Windows Phone 7

In this blog post, I will try to create a sample app in which we store the page state. By default, once you move away from your windows phone app, the page state is not stored. We need to take measures to store the page state when deactivating and restore the page state when activating.
Read on to see the code snippets and explanation -
Let's look at the XAML first -
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <StackPanel>
         <TextBlock Text="Move the slider" />
         <Slider x:Name="sl" Maximum="100" Minimum="0" />
         <TextBox x:Name="tb" Text="{Binding ElementName=sl, Path=Value, Mode=TwoWay}" ></TextBox>
    </StackPanel>
</Grid>
In this XAML, I just have one slider and a textbox bound to slider value, so that it gives us a visual representation of the slider value. The Mode is TwoWay so I can update the value in textbox and slider will position itself accordingly.

Let's take a look at the .cs file now -
public partial class MainPage : PhoneApplicationPage
    {
        bool isNewInstance = false;
        public MainPage()
        {
            InitializeComponent();
            isNewInstance = true;
        }

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

            PageStateSaver.PreserveSliderState(this.State, this.sl);

            isNewInstance = false;

            this.State["PreservingPageState"] = true;
        }

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

            if (isNewInstance && this.State.ContainsKey("PreservingPageState"))
            {
                PageStateSaver.RestoreSliderState(this.State, this.sl, 0.0);
            }
        }
    }
In this code, we have overridden two events. OnNavigatedFrom is called when you are navigating away from the application. In this method, we store the state of slider. OnNavigatedTo is called when we are navigating back to the application. In this method, we restore the state of the slider. PageStateSaver is a static class with these helper methods. Let's take a look at the class code-
public static class PageStateSaver
    {
        internal static void PreserveSliderState(System.Collections.Generic.IDictionary<string, object> state, Slider slider)
        {
            state[slider.Name + "_Value"] = slider.Value;
        }

        internal static void RestoreSliderState(System.Collections.Generic.IDictionary<string, object> state, Slider slider, double defaultVal)
        {
            slider.Value = TryGetValue<Double>(state, slider.Name + "_Value", defaultVal);
        }

        private static T TryGetValue<T>(IDictionary<string, object> state, string name, T defaultValue)
        {
            if (state.ContainsKey(name))
            {
                if (state[name] != null)
                    return (T)state[name];
            }
            return defaultValue;
        }
    }
In PreserveSliderState method, we are passing the page's state and the control itself. As you can see, page's state is nothing but a dictionary of string keys and object values. We create our own key and save the slider value object. In RestoreSliderState, we do the opposite. I just copied the TryGetValue code from MSDN, so that when we had multiple controls, we can use the same generic method.
Let's see the results. Image 1 below shows the screen when you startup. 


Move the slider or put a number between 0 and 100 in the textbox and tab out to move out of textbox. This will change the slider value. I changed the value to 50 as shown in the image 2 (BTW, if you press pg up in the emulator, you can use the keyboard to type in values)
Now click on the search button below. This will call the OnNavigatedFrom method and the state will be stored. The search screen will look something similar to image 3.
Now press the back button. When you press the back button, OnNavigatedTo method is called and the state will be restored. The screen will now look exactly as the second image (image 4).
If you comment the OnNavigatedTo and OnNavigatedFrom methods and try this scenario again, you will see that the page state is not stored.
I also found a useful DLL to look at the counters by following steps in the link here .

No comments: