Remember and navigate through multiple sets of state for a single page instance
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="CustomContentStateNavigationSample.StateNavigationPage" xmlns:ns="clr-namespace:CustomContentStateNavigationSample"> <DockPanel> <DockPanel.Resources> <ObjectDataProvider x:Key="usersDataSource" ObjectType="{x:Type ns:Users}"/> <DataTemplate x:Key="NameTemplate"> <TextBlock Text="{Binding Path=Name}"/> </DataTemplate> </DockPanel.Resources> <Button Name="removeBackEntryButton" DockPanel.Dock="Top" Click="removeBackEntryButton_Click" Height="25">Remove Back Entry</Button> <ListBox Name="userListBox" DockPanel.Dock="Top" Height="150" SelectionChanged="userListBox_SelectionChanged" DataContext="{StaticResource usersDataSource}" ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True" ItemTemplate="{StaticResource NameTemplate}" /> <ListBox Name="logListBox" ScrollViewer.CanContentScroll="True" ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.VerticalScrollBarVisibility="Visible"></ListBox> </DockPanel> </Page> //File:Window.xaml.vb Imports System Imports System.Collections.ObjectModel Imports System.Windows Imports System.Windows.Controls Imports System.Windows.Navigation Imports System.Collections.Generic Imports System.Text Namespace CustomContentStateNavigationSample Public Partial Class StateNavigationPage Inherits Page Implements IProvideCustomContentState Private Sub removeBackEntryButton_Click(sender As Object, e As RoutedEventArgs) If Me.NavigationService.CanGoBack Then Dim entry As JournalEntry = Me.NavigationService.RemoveBackEntry() Dim state As UserCustomContentState = DirectCast(entry.CustomContentState, UserCustomContentState) Me.logListBox.Items.Insert(0, "RemoveBackEntry: " & state.JournalEntryName) End If End Sub Friend Sub userListBox_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) If e.RemovedItems.Count = 0 Then Return End If Dim previousUser As User = TryCast(e.RemovedItems(0), User) Me.logListBox.Items.Insert(0, "AddBackEntry: " & previousUser.Name) Dim userPageState As New UserCustomContentState(previousUser) Me.NavigationService.AddBackEntry(userPageState) End Sub Private Function IProvideCustomContentState_GetContentState() As CustomContentState Implements IProvideCustomContentState.GetContentState Dim currentUser As User = TryCast(Me.userListBox.SelectedItem, User) Me.logListBox.Items.Insert(0, "GetContentState: " & currentUser.Name) Return New UserCustomContentState(currentUser) End Function End Class Public Class User Private m_name As String Public Sub New() End Sub Public Sub New(name As String) Me.m_name = name End Sub Public Property Name() As String Get Return m_name End Get Set m_name = value End Set End Property End Class <Serializable> _ Class UserCustomContentState Inherits CustomContentState Private user As User Public Sub New(user As User) Me.user = user End Sub Public Overrides ReadOnly Property JournalEntryName() As String Get Return Me.user.Name End Get End Property Public Overrides Sub Replay(navigationService As NavigationService, mode As NavigationMode) Dim page As StateNavigationPage = DirectCast(navigationService.Content, StateNavigationPage) Dim userListBox As ListBox = page.userListBox RemoveHandler page.userListBox.SelectionChanged, AddressOf page.userListBox_SelectionChanged page.userListBox.SelectedItem = Me.user AddHandler page.userListBox.SelectionChanged, AddressOf page.userListBox_SelectionChanged End Sub End Class Public Class Users Inherits ObservableCollection(Of User) Public Sub New() Me.Add(New User("A")) Me.Add(New User("B")) Me.Add(New User("C")) Me.Add(New User("D")) Me.Add(New User("E")) Me.Add(New User("F")) Me.Add(New User("G")) End Sub End Class End Namespace