Cancelling a Navigation Request using Prism v4 Region Navigation with Silverlight Frame Navigation

I have had inquiries from developers asking how to implement cancelling a navigation request when using Prism Region Navigation with Silverlight Frame Navigation.

This is a follow up blog post to Integrating Prism v4 Region Navigation with Silverlight Frame Navigation.  Please read this blog post if you have not already done so.

If you have not read the blog post Prism v4 Region Navigation Pipeline, please read this to get an understanding of Prism Region Navigation, the interfaces and the pipeline.  This blog post also covers IConfirmNavigationRequest in detail.

Background

When using Prism region navigation with WPF or Silverlight, developers can implement the IConfirmNavigationRequest interface and in the ConfirmNavigationRequest method, display a dialog, get a response and invoke the callback that was passed as an argument to ConfirmNavigationRequest.  This dialog does not have to be a modal or thread blocking dialog because the Prism Region Navigation pipeline is halted until the callback is invoked.

In order for a region navigation request to be cancelled in a Silverlight application that also uses the Silverlight frame navigation framework, a modal dialog is required when getting the response from the user.  This is because navigation is initiated by the Silverlight frame navigation framework and not the Prism region navigation.  Even if the Prism region navigation is used to initiate the request, the request is still routed to Silverlight frame navigation framework for processing.  The Silverlight frame navigation framework does not support halting the request like the Prism navigation API does, this is why a thread blocking dialog is required to get the input from the user before allowing the navigation request to continue processing.

Prism Documentation on Interaction Requests

Please read the following Prism documentation on Interaction Requests before proceeding.  This fully explains the concepts of the Interaction Request and I won’t repeat that content here.

https://msdn.microsoft.com/en-us/library/gg405494(v=PandP.40).aspx#UserInteractionPatterns

How to Implement Cancelling a Prism 4 Navigation Request when using Silverlight Frame Navigation

  • In the view, set up a Prism Interaction Request in the XAML
  • In the view model expose public property of type InteractionRequest<Confirmation>
  • In the view model implement IConfimNavigationRequest

The following XAML snippet is from the ItemView.xaml file.

  • The NavigationRequest property exposed on the view model
  • The MessageBoxNotificationAction is in MessageBoxNotificationAction.cs. 

 

 <ie:Interaction.Triggers>
    <prism:InteractionRequestTrigger SourceObject="{Binding NavigationRequest}">
        <infra:MessageBoxNotificationAction />
    </prism:InteractionRequestTrigger>
</ie:Interaction.Triggers>

The below code snippet is from MessageBoxNotificationAction.cs.

The Silverlight MessageBox is used to get the response from the user.  The Silverlight MessageBox is a thread blocking message box.  This is required when cancelling a Silverlight Frame navigation request.  Currently, the Silverlight MessageBox is the only thread blocking message box available in Silverlight.  Unfortunately this message box can’t be styled or modified by the developer.

 public class MessageBoxNotificationAction : TriggerAction<FrameworkElement> {

    protected override void Invoke(object parameter) {
        var args = parameter as InteractionRequestedEventArgs;
        if(args == null) {
            return;
        }

        var confirmation = (Confirmation)args.Context;
        MessageBoxResult result = MessageBox.Show(confirmation.Content.ToString(), confirmation.Title, MessageBoxButton.OKCancel);

        confirmation.Confirmed = result == MessageBoxResult.OK;
        args.Callback();
    }
}

The below three code snippets are from ItemViewModel.cs.

The above view XAML data binds to the below NavigationRequest property exposed on the view model.

 public InteractionRequest<Confirmation> NavigationRequest { get; private set; }

The NavigationRequest property is initialized in the view model constructor.

 [ImportingConstructor]
public ItemViewModel(IRegionManager regionManager) {
    _regionManager = regionManager;
    NavigationRequest = new InteractionRequest<Confirmation>();
}

The below code is the implementation for the IConfirmNavigationRequest interface. IConfirmNavigationRequest derives from the INavigationRequest interface and adds a single method ConfirmNavigationRequest.

 void IConfirmNavigationRequest.ConfirmNavigationRequest(NavigationContext navigationContext, Action<Boolean> continuationCallback) {
    this.NavigationRequest.Raise(
        new Confirmation {
            Content = "Would you like to continue navigating away?",
            Title = "Navigation Confirmation"
        }, confirmation => continuationCallback(confirmation.Confirmed));
}

During the processing of the navigation request the above ConfirmNavigationRequest method will be called causing the following code to be executed:

  • Raise method on the InteractionRequest is invoked.  (NavigationRequest property exposes InteractionRequest)
  • The triggers in the XAML trigger the above MessageBoxNotificationAction.Invoke method
  • The result of the MessageBoxNotificationAction.Invoke method are returned in the Confirmation, Confirmed property
  • The Prism Region Navigation API will either cancel or continue the navigation request based on the Confirm property

Running the Sample Code

Requirements: you must download Prism 4 or later and run the RegisterPrismBinaries.bat batch file. The Prism v4 Readme covers this file in detail. If you do not want to run this batch file, you'll need to remove and re-add the references to the Prism assemblies.

I have attached a modified version of the code that demonstrates cancelling a navigation request.  To see this in action, run the application, select Inventory in the menu bar, select an inventory item to edit, then press the Close button on the inventory item form.  A MessageBox will prompt you to continue the navigation or cancel it.

Comments

Microsoft values your opinion about our products, guidance, documentation and samples.

Thank you for your feedback and have a great day,

Karl Shifflett

Patterns & Practices Prism Team

SilverlightPrismv4IntegratedNavigationWithCancellationEnabled.zip