Prism框架提供了坚实的基础,用于创建可以随时间发展、不紧密耦合、可以由大型团队独立开发、可混合使用且可测试的商业应用程序。Prism 4引入了导航API,它通过接管对象创建和将对象放置在目标区域的责任,极大地简化了应用程序开发。
Prism库旨在支持可以针对WPF和Silverlight的应用程序,并且具有很好的代码重用性。虽然并非所有开发人员都需要这种能力,但为了完全支持这种场景,进行了很多思考和设计决策。
在设计时考虑到这种能力的API之一是导航API;具体来说,是导航请求的确认。实现IConfirmNavigationRequest接口的对象可以选择否决导航请求。为了支持Silverlight不允许阻塞对话框的限制,IConfirmNavigationRequest.ConfirmNavigationRequest方法必须编写得让Silverlight对象能够在不阻塞对话框的情况下参与否决导航请求。
在实践中,导航请求在调用回调之前会暂停。这种设计使Silverlight开发人员能够实现各种UI解决方案来提示用户,例如Prism交互请求。
在WPF开发中,发现不得不跳过上述步骤来实现导航确认,而实际上WPF已经内置了支持模态、UI阻塞对话框的功能。为了简化WPF应用程序,创建了一个替换Prism RegionNavigationService的实现,允许同步导航确认。
实现非常简单,只需要向Prism库添加一个类和一个接口并重新编译。RegionNavigationSynchronousService是标准RegionNavigationService的替代品。这个类使用了新的同步(阻塞)导航确认接口IConfirmNavigationRequestSynchronous,如下所示:
public interface IConfirmNavigationRequestSynchronous : INavigationAware
{
///
///
/// 确定此实例是否允许从当前导航离开。
///
/// 导航上下文。
/// 如果允许导航,则为true;否则为false。
Boolean ConfirmNavigationRequestSynchronous(NavigationContext navigationContext);
}
默认情况下,Prism在容器中自动注册RegionNavigationService作为引导管道的一部分。但是,希望使用WPF友好的同步确认服务RegionNavigationSynchronousService。
所需要做的就是在引导器中覆盖ConfigureContainer方法并注册RegionNavigationSynchronousService,如下所示:
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();
Application.Current.MainWindow = shell;
Application.Current.MainWindow.Show();
return shell;
}
protected override void ConfigureContainer() {
base.ConfigureContainer();
// 注册新的导航服务,使用同步导航确认
this.Container.RegisterType(typeof(IRegionNavigationService), typeof(RegionNavigationSynchronousService));
}
}
}
请不要在视图模型中放置MessageBox代码!这只是演示目的,并且为了保持代码简单。请使用抽象UI对话框的对话框服务。
以下代码来自包含的下载,位于CustomerMaintenanceViewModel中。以下ConfirmNavigation属性允许演示确认或不确认,但不是导航API的一部分。此方法返回true或false以继续导航请求或不继续。
public Boolean ConfirmNavigationRequestSynchronous(NavigationContext navigationContext) {
if (this.ConfirmNavigation) {
if (MessageBox.Show("关闭表单并导航?", "确认导航", MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.OK) {
return true;
}
return false;
}
return true;
}
这是一个非常简单的Prism应用程序,演示了确认导航请求和区域生命周期。状态栏指示右侧ContentRegion中视图的名称。当打开或关闭视图时,将显示其名称;对于客户,将显示客户编号。
打开代码,将在几分钟内掌握这个。下载后,不要忘记“解除阻止”从互联网下载的zip文件,然后再解压缩。
下载包括一个示例Prism解决方案,可以在不修改Prism库代码的情况下运行。在解决方案中包含了一个\Lib文件夹,其中包含预构建的修改后的Prism库代码。
还包含了两个文件在\PrismSource文件夹中,可以将这两个文件添加到Prism库中。简单地将这两个文件复制到以下文件夹并重新编译Prism。现在可以选择在WPF项目中使用一个更简单的导航确认API。
这只在WPF中有效,不适用于Silverlight。如果有在WPF和Silverlight之间共享代码的要求,这将不起作用,因为Silverlight要求导航确认是异步的。