Visually Located


Restore the last visible Hub Section with the DefaultSectionIndex

I previously blogged about transitioning your app from the Panorama control to the new Hub control in Windows Phone 8.1 runtime apps. That post served as a starting point for moving away from the Silverlight Panorama control. As time goes by we find more things that need to be moved over. One of those is the ability to set (or get) the the selected PanoramaItem. This is a really important feature. According to the design guidelines for the Panorama.

For subsequent visits, the user should be taken back to the pane where they left off when user revisits the same Panorama control.

The design guidelines for the Hub has the following

For subsequent visits to the same hub control, take the user back to the section where they left off.

You can see this experience in the People hub.

In the Panorama control you could get the current visible item through either the SelectedIndex or the SelectedItem property, or be notified when the visible item changes with the SelectionChanged event. Following the guideline was a little hard however because the best way to ensure the pano opened to the correct page is with the DefaultItem property. The reason this was hard is because this excepts a PanoramoItem rather than an index. With an index, it could easily be saved and retrieved. With an item, it’s a little harder to save this information off and then get it the next time the app opened. While this was difficult, it was still doable.

The Hub control keeps this same workflow but has made an improvement. Instead of setting a default item, you now set an index with the DefaultSectionIndex property. The downside is the Hub control does not have a SelectedIndex or SelectedItem property. Fear not! The cheese was not removed, just moved. You can get the currently visible section with the SectionsInView property. This property returns an IList<HubSection> in which the first item in the list is the visible section and the second item in the list is the section that is peeking in on the right. With the SectionsInView and the Sections property, you can get the currently selected index.

var section = hub.SectionsInView[0];
var selectedIndex = hub.Sections.IndexOf(section);
Now that you have the visible section, you can save that off whenever you need to navigate away from your hub page. This can be done when navigating to a new page, or when the exiting the app. The hub even fires an event when the sections in view change.
private void OnSectionsInViewChanged(object sender, SectionsInViewChangedEventArgs e)
    var section = Hub.SectionsInView[0];
    ViewModel.DefaultIndex = Hub.Sections.IndexOf(section);

The viewmodel would set the index in the local settings so that it can easily be retrieved the next time the app is opened.

public class HubViewModel
    public int DefaultIndex
            object defaultIndex;
            if (ApplicationData.Current.LocalSettings.Values.TryGetValue("defaultIndex", out defaultIndex))
                return (int) defaultIndex;
            return 0;
        set { ApplicationData.Current.LocalSettings.Values["defaultIndex"] = value; }

And then we bind to the property in our Hub

<Hub x:Name="Hub" x:Uid="Hub" Header="application name" Background="{ThemeResource HubBackgroundImageBrush}"
     DefaultSectionIndex="{Binding DefaultIndex}"
    <!-- setions -->

Now every time the user opens the app the hub will be on the last page they left from!

Download the sample solution and try it out.

blog comments powered by Disqus