Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Simplifying Prism WPF Navigation – Synchronous Navigation Confirmation

0.00/5 (No votes)
8 Jan 2015 1  
Microsoft patterns & practices Prism 4 library and guidance gives WPF and Silverlight developers a very solid foundation for creating business applications.

Microsoft patterns & practices Prism 4 library and guidance gives WPF and Silverlight developers a very solid foundation for creating business applications. Adopting Prism patterns and library features guides the developer towards creating applications that: can evolve over time, are not tightly coupled, can be independently developed across a large team, are Blendable, and testable.

New to Prism 4 was the Navigation API’s. The use of the Navigation API’s greatly simplifies application development because the Navigation API takes over the responsibility of object creation and siting objects in the target region.

The Prism library is designed to support applications that can target WPF and Silverlight with good code reuse. While not all developers need this capability, a lot of thought and design decisions were made to fully support this scenario.

One API that took this capability into account while being designed is the Navigation API; specifically the confirmation of a navigation request. Objects that implement IConfirmNavigationRequest have the option to veto a navigation request. In order to support the limitation that Silverlight does not allow blocking dialog boxes, the IConfirmNavigationRequest.ConfirmNavigationRequest method had to be written so that Silverlight objects could participate in vetoing a navigation request without a blocking dialog.

Without going into all the details (you can read them here), objects that implement IConfirmNavigationRequest are required to invoke the callback in the ConfirmNavigationRequest method arguments. Objects are free to implement any vetoing code they want as long as the callback is invoked.  In practice the navigation request is halted until the callback is invoked. This design enables Silverlight developers to implement a variety UI solutions for prompting the user, for example the Prism Interaction Request.

I’ve found that I’m my WPF development that I had to jump through the above hoops just to have navigation confirmation, when in fact WPF has out of the box support for modal, UI blocking dialogs. In an effort to simplify my WPF applications I’ve created a replacement for the Prism RegionNavigationService that allows for synchronous navigation confirmation.

The implementation is very straightforward and only requires that you add one class and one interface to the Prism library and recompile it.

The RegionNavigationSynchronousService is the replacement for the stock RegionNavigationService. This class uses the new synchronous (blocking) navigation confirmation interface IConfirmNavigationRequestSynchronous, listed below.

C#
public interface IConfirmNavigationRequestSynchronous : INavigationAware
{
    /// <summary>
    /// Determines whether this instance approves being navigated away from.
    /// </summary>
    /// <param name="navigationContext">The navigation context.</param>
    Boolean ConfirmNavigationRequestSynchronous(NavigationContext navigationContext);
}

By default, Prism automatically registers the RegionNavigationService in the container as part of the bootstrapping pipeline. However, we want to use the WPF friendly synchronous confirmation service, RegionNavigationSynchronousService.

All that is required is to override the ConfigureContainer method in your bootstrapper and register RegionNavigationSynchronousService as I’ve done below.

C#
namespace TestBench {
    using System.Windows;
    using Microsoft.Practices.Prism.Modularity;
    using Microsoft.Practices.Prism.Regions;
    using Microsoft.Practices.Prism.UnityExtensions;
    using Microsoft.Practices.Unity;
    using TestBench.Customers;

    class Bootstrapper : UnityBootstrapper {
        protected override IModuleCatalog CreateModuleCatalog() {
            var catalog = new ModuleCatalog();
            catalog.AddModule(typeof (CustomersModule));
            return catalog;
        }

        protected override DependencyObject CreateShell() {
            var shell = this.Container.Resolve<ShellView>();
            Application.Current.MainWindow = shell;
            Application.Current.MainWindow.Show();
            return shell;
        }

        protected override void ConfigureContainer() {
            base.ConfigureContainer();

            // register the new navigation service that uses synchronous navigation 
            // confirmation instead of the async confirmation.
            this.Container.RegisterType(typeof(IRegionNavigationService), 
                typeof(RegionNavigationSynchronousService));
        }
    }
}

Below is a very simple implementation.

PLEASE do not put MessageBox code in your view models!  This is for demo purposes only and to keep the code simple.  Please use a dialog service that abstracts the UI dialog away from the view model.

The below code is from the included download and is in the CustomerMaintenanceViewModel. The below ConfirmNavigation property allows the demo to confirm or not but is not part of the Navigation API. This method returns true or false to continue the navigation request or not.

C#
public Boolean ConfirmNavigationRequestSynchronous(NavigationContext navigationContext) {
    if (this.ConfirmNavigation) {
        if (MessageBox.Show("Close form and navigate?", "Confirm Navigation", 
            MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.OK) {
            return true;
        }
        return false;
    }
    return true;
}

Demo Application

SyncDemo

Very simple Prism application that demonstrates confirming navigation requests and region lifetime. The status bar indicates the views in the ContentRegion on the right.  As you open or close views their name will be displayed; for the Customers, the customer number will be displayed.

Crack the code open, you’ll have this down in a few minutes.

Download

As always, don’t forget to “Unblock” the zip file after downloading from the Internet before you unzip it.

Synchronous Prism Navigation (177KB)

The download includes a sample Prism solution that your can run without modifying your Prism library code.  I’ve included a \Lib folder in the solution with pre-built, modified Prism library code.

I’ve also included two files in the \PrismSource folder that you can add to your Prism library. Simply copy these two files into the below folder and recompile Prism. You now have the option to use a simpler navigation confirmation API in your WPF projects. 

This only works in WPF and NOT Silverlight.  If you have the requirement to share code between WPF and Silverlight this will not work because Silverlight requires the navigation confirmation to be async.

SyncNav

Have a great day,

Just a grain of sand on the worlds beaches.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here