Search code examples
c#windows-runtimewindows-phonewindows-store-appswindows-phone-8.1

How to save a page state?


In a Windows Runtime app, I load data like this:

private async void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
    var userId = e.NavigationParameter as string;
    List<User> followers = GetFollowers(userId);
    this.DefaultViewModel["Followers"] = followers;
}

then user can select an item from ListView:

private void ContentListView_ItemClick(object sender, ItemClickEventArgs e)
{
    var selectedItem = e.ClickedItem as User;

    if (!Frame.Navigate(typeof(FollowersPage), selectedItem.UserId))
    {
        throw new Exception(this.resourceLoader.GetString("NavigationFailedExceptionMessage"));
    }
}

So it navigates forward to the same page, but shows new followers.

The problem is that when it navigates back, it loads data again and shows from the beginning of the list rather than showing the last item selected.

So how to save a List of data in NavigationHelper_SaveState and how to load it again in NavigationHelper_LoadState with last position in the list? thanks.


Solution

  • Here's a basic semi-tested example you can start from. You'll need to modify it to fit your exact circumstances. Some of it is adapted from here.

    void NavigationHelper_SaveState(object sender, SaveStateEventArgs e)
    {
        var isp = (ItemsStackPanel)listview.ItemsPanelRoot;
        int firstVisibleItem = isp.FirstVisibleIndex;
        e.PageState["FirstVisibleItemIndex"] = firstVisibleItem;
    
        // This must be serializable according to the SuspensionManager
        e.PageState["Followers"] = this.DefaultViewModel["Followers"];
    }
    
    void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
    {
        // Do we have saved state to restore?
        if (e.PageState != null)
        {
            // Restore list view items
            this.DefaultViewModel["Followers"] = (WhateverType)e.PageState["Followers"];
    
            // Restore scroll offset
            var index = (int)e.PageState["FirstVisibleItemIndex"];
            var container = listview.ContainerFromIndex(index);
            listview.ScrollIntoView(container);
        }
        else
        {
            // Load data for the first time
            var userId = e.NavigationParameter as string;
            List<User> followers = GetFollowers(userId);
            this.DefaultViewModel["Followers"] = followers;
        }
    }