Prism Step5 PrismApplication

7.1 Prism 更新以后,官方移除了 Bootstrapper 的方式引导启动 Prism 应用,取而代之的是 PrismApplication。

首先是 app.xaml 中的改动:

1
2
3
4
5
6
7
8
9
<prism:PrismApplication x:Class="Regions.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
xmlns:local="clr-namespace:Regions">
<Application.Resources>

</Application.Resources>
</prism:PrismApplication>

在6.x中,这里还是一个Application,现在已经改成prism:PrismApplication,然后是,App.xaml.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using Prism.Ioc;
using Prism.Unity;
using Regions.Views;
using System.Windows;

namespace Regions
{
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{

}
}
}

这里用了 Prism.Ioc和Prism.Unity,新的Prism.IoC命名空间,它创建了一个依赖注入容器的抽象。您现在只使用Prism提供的IContainerRegistry和IContainerProvider接口,而不是直接使用容器类。该IContainerProvider 接口用于从容器解析服务,IContainerRegistry 用于与容器登记类型。而之前的Unity也不再使用了,现在使用Prism.Unity,上面App.xaml.cs代码中 的PrismApplication 正是存在于Prism.Unity,如果你需要从6.x升级到7.x,所有的unity引用都需要删掉,重新添加Prism.Unity,并且修改相关代码。

Regions是应用程序UI的逻辑区域,它很像一个PlaceHolder,Views在Regions中展现,很多种控件可以被用作Region :ContentControl、ItemsControl、ListBox、TabControl。

简单的说,就是一个容器(区域适配器),用来装载Views的。这像WinForms中的Container控件Panel,里面可以放置其他控件。在PRISM中,Views也是用户控件(UserControl)

Region的注册方式:

说一句题外话,XAML是什么:

XAML(Extensible Application Markup Language)是Windows Presentation Foundation(WPF)的一部分,是微软开发的一种基于XML、基于声明,用于初始化结构化值和对象的用户界面描述语言,它有着HTML的外观,又揉合了XML语法的本质,例如:可以使用

指定了Region,接下来就为Region指定View了。

在Views目录下面,新建一个UserControl,并在Grid控件内,加一个TextBlock,写上字,标识这是View A。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using Prism.Regions;
using System.Windows;

namespace ViewDiscovery.Views
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow(IRegionManager regionManager)
{
InitializeComponent();
//view discovery
regionManager.RegisterViewWithRegion("ContentRegion", typeof(ViewA));
}
}
}

[7.1updated]虽然7.1不再使用Unity,但这不影响我们来了解依赖注入容器在prism中的作用
prism是使用依赖注入容器实现依赖注入的,这里我们使用的是Unity,Prism同样支持Mef容器实现依赖注入。[7.1updated]现已不再支持Mef容器了

如果使用 Unity 实例化一个类,该类的构造函数依赖一个或多个其他类,则 Unity 会为构造函数自动创建参数中指定的被依赖的类的实例。上面MainWindow的构造函数中的regionManager参数,就是Unity自动创建的。

RegionManager
代码中RegionManager的RegisterViewWithRegion方法将我们的视图(View)和区域适配器(Region)进行关联

RegionManager,它实现了IRegionManager接口。IRegionManager接口包含一个只读属性Regions,是Region的集合(这个集合是从xaml中获取的,也就是我们定义的那些),RegionManager的实例会使用他们,并将view注册给他们。

View Discovery和View Injection
在Prism中有两种方式来定义视图与Region之间的映射关系——View Discovery和View Injection。

上面的regionManager.RegisterViewWithRegion(“ContentRegion”, typeof(ViewA));就是View Discovery。

然后我们看一下View Injection:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using Prism.Ioc;
using Prism.Regions;
using System.Windows;

namespace ViewInjection.Views
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
IContainerExtension _container;
IRegionManager _regionManager;

public MainWindow(IContainerExtension container, IRegionManager regionManager)
{
InitializeComponent();
_container = container;
_regionManager = regionManager;
}

private void Button_Click(object sender, RoutedEventArgs e)
{
var view = _container.Resolve<ViewA>();
IRegion region = _regionManager.Regions["ContentRegion"];
region.Add(view);
}
}
}

他从_regionManager中获取Region,然后使用IRegion.Add(View)的方式来向已有的Region中添加View。

视图的激活与取消激活

激活:

_region.Activate(_viewA);

取消:

_region.Deactivate(_viewA);

评论