Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Simplifying Prism WPF Navigation – Synchronous Navigation Confirmation

, 6 Sep 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
Simplifying Prism WPF Navigation – Synchronous Navigation Confirmation

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 APIs. The use of the Navigation APIs 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 in 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:

public interface IConfirmNavigationRequestSynchronous : INavigationAware
{
    /// <span class="code-SummaryComment"><summary>
</span>    /// Determines whether this instance approves being navigated away from.
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><param name="navigationContext">The navigation context.</param>
</span>    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:

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.

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.

The download includes a sample Prism solution that you 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.


Filed under: C#, CodeProject, Navigation, Prism, WPF General

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Karl Shifflett
Architect Gayle Manufacturing Company
United States United States
Karl loves .NET, WPF, WCF, ASP.NET, VB.NET and C#.
 
Awards:
 
  • December 2008 VB.NET Code Project Article Award
  • 2009 Code Project MVP
  • 2008 Code Project MVP
  • 2008 Microsoft MVP - Client App Dev
  • December 2007 VB.NET Code Project Article Award
  • Gold Medal Winner at IBM's 1998 PROIV Programming Contest in Las Vegas
Click here to check out my Blog
 
Click here to learn about Mole 2010 debugging tool for Visual Studio 2010
 
Click here to read about XAML Power Toys
 

Just a grain of sand on the worlds beaches.

Follow on   Twitter

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.150224.1 | Last Updated 6 Sep 2011
Article Copyright 2011 by Karl Shifflett
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid