Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

Navigating Back using State History with BuildIt.Lifecycle

So far I’ve only discussed transitioning between states with an assumption that every transition is forward looking and that our state manager doesn’t track any sort of history. Other than simple applications, or poorly architected applications that don’t make use of the devices back navigation feature, it is a requirement for most applications to track the page/view/state that the user was previously in, allowing them to easily navigate back to where they just came from. This doesn’t fit into the normal concept of a finite state machine, since this wouldn’t normally have any “memory”. However, our state manager can easily be extended to include a history of which states have been visited.

Again, let’s start with updating the user interface on our simple application. On the settings page we didn’t have any way to get back to the main/home page of our application. I’ll add a new button, resulting in the following XAML and codebehind:

<Page x:Class="SimpleStates.Pages.SettingsPage"
      xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:SimpleStates.Pages"
      xmlns:d="
http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d">
    <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="Settings Page"
                   VerticalAlignment="Center"
                   HorizontalAlignment="Center"
                   FontSize="40" />
        <Button Click="GoBackClick">Go Back</Button>
    </StackPanel>
</Page>

public sealed partial class SettingsPage
{
    public SettingsPage()
    {
        InitializeComponent();
    }
    private void GoBackClick(object sender, RoutedEventArgs e)
    {
        (DataContext as SettingsViewModel).Complete();
    }
}

The only change I needed to make to the SettingsViewModel is to change the back class. Note that in this case since there is only one way that the state can be exited, I’m going to use the built in DefaultCompletion enumeration, which has a single Complete value.

public class SettingsViewModel : BaseViewModelWithCompletion<DefaultCompletion>
{
    public void Complete()
    {
        OnComplete(DefaultCompletion.Complete);
    }
}

The only thing left to do is to update the state declaration for my application to change to the previous state when the Settings state is Complete, as follows:

StateManager.GroupWithViewModels<AppStates>()
    .StateWithViewModel<AppStates, MainViewModel>(AppStates.Home)
        .OnComplete(MainCompletion.Settings).ChangeState(AppStates.Settings)
        .OnComplete(MainCompletion.About).ChangeState(AppStates.About)
        .EndState()
    .StateWithViewModel<AppStates, SettingsViewModel>(AppStates.Settings)
        .OnComplete(DefaultCompletion.Complete).ChangeToPreviousState()
        .EndState()
    .StateWithViewModel<AppStates, AboutViewModel>(AppStates.About);

The state history feature does allow for skipping states that are in the history, so you can easily return to the start of an application by changing to the corresponding state using ChangeBackToState instead of ChangeState.

Note: The state history feature can be turned on/off on individual state groups. By default TrackHistory is disabled for regular state groups. State groups that have corresponding view models has TrackHistory enabled by default.

Pingbacks and trackbacks (1)+

Comments are closed