Windows Phone and MVVM Light: NavigationService and CanGoBack

By in , , ,
No comments

MVVM Light is a simple yet powerful framework for developing apps, and with the latest version 5 includes a new cross-platform NavigationService to aid in abstracting the navigation component of your apps. However, looking at the implementation of the INavigationService interface, there is no property available to support the idea of CanGoBack, which is important for devices like Windows Phone that include a back button. The default code that gets generated for the HardwareButtons.BackPressed event relies on the Windows implementation of NavigationService, which does have such a property, as shown in this example:

void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)

{

    if (NavigationService.CanGoBack())

    {

        NavigationService.GoBack();

        //Indicate the back button press is handled so the app does not exit

        e.Handled = true;

    }

}

However since we’re using the MVVM Light version, we need a more generic way to check for navigation history, as well as the ability to call navigation from the MVVM Navigation Service. Fortunately, the CanGoBack property is ultimately a member of the Frame control in the Windows Phone app, so we can simply inspect it there, and if its value is true, call GoBack from the correct NavigationService. In this example, I’m using the ServiceLocator, but of course this can be wrapped in a static property or other accessible place for your app.

void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)

{

    var frame = Window.Current.Content as Frame;

    if (frame.CanGoBack)

    {

        var navigation = ServiceLocator.Current.GetInstance<INavigationService>();

        navigation.GoBack();

        e.Handled = true;

    }

}

Using the Frame also allows us to bind the Visibility property (with the help of a Converter of course) to the CanGoBack property, ensuring that the Back button is only visible on the View if there is a navigation history to return.

<Button x:Name="backButton" Margin="39,59,39,0" Click="backButton_Click"

                Style="{StaticResource NavigationBackButtonNormalStyle}"

                Visibility="{Binding Frame.CanGoBack, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=page, Mode=OneWay}" />

Using this tip we can continue to use the cross-platform NavigationService while still supporting the Back button on both Windows and Windows Phone devices. I hope this was helpful!

The following two tabs change content below.

selaromdotnet

Senior Developer at iD Tech
Josh loves all things Microsoft and Windows, and develops solutions for Web, Desktop and Mobile using the .NET Framework, Azure, UWP and everything else in the Microsoft Stack. His other passion is music, and in his spare time Josh spins and produces electronic music under the name DJ SelArom. His other passion is music, and in his spare time Josh spins and produces electronic music under the name DJ SelArom.