Prism
1. 介绍
Prism [ˈprɪzəm] 为 MVVM 思想开发框架之一。
WPF Prism 是微软提供的一个开源框架,旨在帮助开发人员构建复杂的、模块化和可维护的 WPF 应用程序。Prism 支持 MVVM 设计模式,模块化开发,以及依赖注入,并为 WPF 应用提供导航、事件管理和区域管理的功能。
Prism 的核心组件包括:
-
数据绑定(Data Binding):虽然 Prism 本身不提供数据绑定机制,但它与 WPF 和 Xamarin.Forms 的数据绑定框架紧密集成,可以轻松地将视图模型与视图进行绑定。
-
命令(Commands):Prism 提供了一种简化的方式来处理用户界面中的命令,如按钮点击事件。
-
依赖注入(Dependency Injection):Prism 提供了一个依赖注入容器,可以将应用程序的组件和服务进行解耦,从而提高代码的可测试性和可维护性。
-
区域(Region):是一个UI容器,用于动态加载和卸载不同的视图和组件。
-
导航(Navigation):Prism 提供了一个灵活的导航系统,可以定义视图之间的导航路径,并管理视图的生命周期。
-
模块化(Modularity):Prism 支持模块化设计,将应用程序分解成独立的模块,每个模块负责特定的功能,有助于减少应用程序的复杂性,并能够使开发和维护更加容易。
-
事件聚合器(Event Aggregator):这是一个松散耦合的事件发布/订阅机制,应用程序的不同部分之间进行通信,而不需要直接引用对方。
2. 快速入门
2.1 手动构建 Prism 项目
2.1.1 创建项目

2.1.2 项目结构
目录名称必须为 Models,ViewModels,Views。
将MainWindow.xaml、MainWindow.xaml.cs 移动到 Views目录中。命名空间添加 .Views。

-
MainWindow.xaml
<span style="background-color:#333333"><span style="color:#999977"><</span><span style="color:#7df46a">Window</span> <span style="color:#7575e4">x:Class</span>=<span style="color:#d26b6b">"Prism_WpfApp1.Views.MainWindow"</span> <span style="color:#7575e4">xmlns</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span> <span style="color:#7575e4">xmlns:x</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml"</span> <span style="color:#7575e4">xmlns:d</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/expression/blend/2008"</span> <span style="color:#7575e4">xmlns:mc</span>=<span style="color:#d26b6b">"http://schemas.openxmlformats.org/markup-compatibility/2006"</span> <span style="color:#7575e4">xmlns:local</span>=<span style="color:#d26b6b">"clr-namespace:Prism_WpfApp1"</span> <span style="color:#7575e4">mc:Ignorable</span>=<span style="color:#d26b6b">"d"</span> <span style="color:#7575e4">Title</span>=<span style="color:#d26b6b">"MainWindow"</span> <span style="color:#7575e4">Height</span>=<span style="color:#d26b6b">"450"</span> <span style="color:#7575e4">Width</span>=<span style="color:#d26b6b">"800"</span><span style="color:#999977">></span> <span style="color:#999977"><</span><span style="color:#7df46a">Grid</span><span style="color:#999977">></span> <span style="color:#999977"></</span><span style="color:#7df46a">Grid</span><span style="color:#999977">></span> <span style="color:#999977"></</span><span style="color:#7df46a">Window</span><span style="color:#999977">></span></span> -
MainWindow.xaml.cs
<span style="background-color:#333333"><span style="color:#c88fd0">namespace</span> <span style="color:#8d8df0">Prism_WpfApp1</span>.<span style="color:#b8bfc6">Views</span> { <span style="color:#da924a">/// <summary></span> <span style="color:#da924a">/// MainWindow.xaml 的交互逻辑</span> <span style="color:#da924a">/// </summary></span> <span style="color:#c88fd0">public</span> <span style="color:#c88fd0">partial</span> <span style="color:#c88fd0">class</span> <span style="color:#8d8df0">MainWindow</span> : <span style="color:#b8bfc6">Window</span> { <span style="color:#c88fd0">public</span> <span style="color:#b8bfc6">MainWindow</span>() { <span style="color:#b8bfc6">InitializeComponent</span>(); } } }</span>
2.1.3 安装 Prism 类库
Prism.Unity和Prism.DryIoc是Prism框架的两个依赖注入容器选项。它们的主要功能相似,但底层实现不同:
Prism.Unity:使用Unity容器,这是一个轻量级的、高性能的依赖注入容器,适用于需要高性能和灵活性的场景。Unity容器提供了丰富的功能和扩展性,适合需要高度定制的场景。
Prism.DryIoc:使用DryIoc容器,这是一个快速、轻量级的依赖注入容器,适用于需要快速启动和简单配置的场景。DryIoc以其简洁和高效著称,适合追求性能和简洁性的项目。
Prism.xxx 版本必须为兼容 .NetFramework 版本。

2.1.4 修改 App.xaml
删除StartupUri="Views/MainWindow.xaml"。
手动引入xmlns:prism="http://prismlibrary.com/"
<span style="background-color:#333333"><span style="color:#b8bfc6"><span style="color:#999977"><</span><span style="color:#7df46a">prism:PrismApplication</span> <span style="color:#7575e4">x:Class</span>=<span style="color:#d26b6b">"Prism_WpfApp1.App"</span>
<span style="color:#7575e4">xmlns</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>
<span style="color:#7575e4">xmlns:x</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml"</span>
<span style="color:#7575e4">xmlns:local</span>=<span style="color:#d26b6b">"clr-namespace:Prism_WpfApp1"</span>
<span style="color:#7575e4">xmlns:prism</span>=<span style="color:#d26b6b">"http://prismlibrary.com/"</span><span style="color:#999977">></span>
<span style="color:#999977"><</span><span style="color:#7df46a">Application.Resources</span><span style="color:#999977">></span>
<span style="color:#999977"></</span><span style="color:#7df46a">Application.Resources</span><span style="color:#999977">></span>
<span style="color:#999977"></</span><span style="color:#7df46a">prism:PrismApplication</span><span style="color:#999977">></span></span></span>
2.1.5 修改 App.xaml.cs
1. 出现 CS0263:"App"的部分声明不能指定不同的基类,选中解决方案,右键重新生成解决方案。
2. 必须实现CreateShell 和 RegisterTypes 方法
<span style="background-color:#333333"><span style="color:#b8bfc6"><span style="color:#c88fd0">namespace</span> <span style="color:#8d8df0">Prism_WpfApp1</span>
{
<span style="color:#da924a">/// <summary></span>
<span style="color:#da924a">/// App.xaml 的交互逻辑</span>
<span style="color:#da924a">/// </summary></span>
<span style="color:#c88fd0">public</span> <span style="color:#c88fd0">partial</span> <span style="color:#c88fd0">class</span> <span style="color:#8d8df0">App</span> : <span style="color:#b8bfc6">PrismApplication</span>
{
<span style="color:#c88fd0">protected</span> <span style="color:#c88fd0">override</span> <span style="color:#b8bfc6">Window</span> <span style="color:#b8bfc6">CreateShell</span>()
{
<span style="color:#da924a">//由 Prism 指定启动窗口</span>
<span style="color:#c88fd0">return</span> <span style="color:#b8bfc6">Container</span>.<span style="color:#b8bfc6">Resolve</span><span style="color:#b8bfc6"><</span><span style="color:#b8bfc6">MainWindow</span><span style="color:#b8bfc6">></span>();
}
<span style="color:#da924a">//注册对象</span>
<span style="color:#c88fd0">protected</span> <span style="color:#c88fd0">override</span> <span style="color:#c88fd0">void</span> <span style="color:#b8bfc6">RegisterTypes</span>(<span style="color:#b8bfc6">IContainerRegistry</span> <span style="color:#b8bfc6">containerRegistry</span>)
{
}
<span style="color:#da924a">//手动指定 View 与 ViewModel关系</span>
<span style="color:#da924a">/*protected override void ConfigureViewModelLocator()</span>
<span style="color:#da924a">{</span>
<span style="color:#da924a">base.ConfigureViewModelLocator();</span>
<span style="color:#da924a">ViewModelLocationProvider.Register<视图名, 视图模型名>();</span>
<span style="color:#da924a">}*/</span>
}
}</span></span>
2.2 数据绑定及命令
2.2.1 MainWindow.xaml
<span style="background-color:#333333"><span style="color:#b8bfc6"><span style="color:#999977"><</span><span style="color:#7df46a">Window</span> <span style="color:#7575e4">x:Class</span>=<span style="color:#d26b6b">"Prism_WpfApp1.Views.MainWindow"</span>
<span style="color:#7575e4">xmlns</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>
<span style="color:#7575e4">xmlns:x</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml"</span>
<span style="color:#7575e4">xmlns:d</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/expression/blend/2008"</span>
<span style="color:#7575e4">xmlns:mc</span>=<span style="color:#d26b6b">"http://schemas.openxmlformats.org/markup-compatibility/2006"</span>
<span style="color:#7575e4">xmlns:local</span>=<span style="color:#d26b6b">"clr-namespace:Prism_WpfApp1"</span>
<span style="color:#7575e4">mc:Ignorable</span>=<span style="color:#d26b6b">"d"</span>
<span style="color:#7575e4">Title</span>=<span style="color:#d26b6b">"MainWindow"</span> <span style="color:#7575e4">Height</span>=<span style="color:#d26b6b">"450"</span> <span style="color:#7575e4">Width</span>=<span style="color:#d26b6b">"800"</span><span style="color:#999977">></span>
<span style="color:#999977"><</span><span style="color:#7df46a">Grid</span><span style="color:#999977">></span>
<span style="color:#999977"><</span><span style="color:#7df46a">StackPanel</span><span style="color:#999977">></span>
<span style="color:#999977"><</span><span style="color:#7df46a">TextBox</span> <span style="color:#7575e4">Text</span>=<span style="color:#d26b6b">"{Binding Name}"</span> <span style="color:#7575e4">Width</span>=<span style="color:#d26b6b">"200"</span> <span style="color:#7575e4">Margin</span>=<span style="color:#d26b6b">"50"</span><span style="color:#999977">/></span>
<span style="color:#999977"><</span><span style="color:#7df46a">Button</span> <span style="color:#7575e4">Command</span>=<span style="color:#d26b6b">"{Binding BtnCommand}"</span> <span style="color:#7575e4">Content</span>=<span style="color:#d26b6b">"按钮"</span> <span style="color:#7575e4">Width</span>=<span style="color:#d26b6b">"200"</span><span style="color:#999977">/></span>
<span style="color:#999977"></</span><span style="color:#7df46a">StackPanel</span><span style="color:#999977">></span>
<span style="color:#999977"></</span><span style="color:#7df46a">Grid</span><span style="color:#999977">></span>
<span style="color:#999977"></</span><span style="color:#7df46a">Window</span><span style="color:#999977">></span></span></span>
2.2.2 MainWindowViewModel
BindableBase 实现了 INotifyPropertyChanged 接口,提供了Model数据变化通知UI更新的功能。
DelegateCommand 实现了 ICommand等接口,实现了命令及拓展功能。
实现自动绑定ViewModeL,不需要手动将 ViewModel 绑定到 DataContext:
窗体|页面|用户控件必须放到Views目录下。
视图模型必须放到ViewModels目录下。
模型模型的名称,必须是窗体名称开头,且以ViewModel结尾。
prism:ViewModelLocator.AutoWireViewModel="True",默认为true。
<span style="background-color:#333333"><span style="color:#b8bfc6"><span style="color:#c88fd0">namespace</span> <span style="color:#8d8df0">Prism_WpfApp1</span>.<span style="color:#b8bfc6">ViewModels</span>
{
<span style="color:#c88fd0">public</span> <span style="color:#c88fd0">class</span> <span style="color:#8d8df0">MainWindowViewModel</span> : <span style="color:#b8bfc6">BindableBase</span>
{
<span style="color:#c88fd0">private</span> <span style="color:#1cc685">string</span> <span style="color:#b8bfc6">_name</span> <span style="color:#b8bfc6">=</span> <span style="color:#d26b6b">"zs"</span>;
<span style="color:#c88fd0">public</span> <span style="color:#1cc685">string</span> <span style="color:#b8bfc6">Name</span>
{
<span style="color:#c88fd0">get</span> { <span style="color:#c88fd0">return</span> <span style="color:#b8bfc6">_name</span>; }
<span style="color:#c88fd0">set</span>
{
<span style="color:#b8bfc6">_name</span> <span style="color:#b8bfc6">=</span> <span style="color:#c88fd0">value</span>;
<span style="color:#b8bfc6">RaisePropertyChanged</span>();
}
}
<span style="color:#c88fd0">public</span> <span style="color:#b8bfc6">ICommand</span> <span style="color:#b8bfc6">BtnCommand</span> { <span style="color:#c88fd0">get</span>; <span style="color:#c88fd0">set</span>; }
<span style="color:#c88fd0">public</span> <span style="color:#b8bfc6">MainWindowViewModel</span>()
{
<span style="color:#b8bfc6">BtnCommand</span> <span style="color:#b8bfc6">=</span> <span style="color:#c88fd0">new</span> <span style="color:#b8bfc6">DelegateCommand</span>(<span style="color:#b8bfc6">GetValue</span>);
}
<span style="color:#c88fd0">public</span> <span style="color:#c88fd0">void</span> <span style="color:#b8bfc6">GetValue</span>()
{
<span style="color:#b8bfc6">MessageBox</span>.<span style="color:#b8bfc6">Show</span>(<span style="color:#b8bfc6">Name</span>);
<span style="color:#b8bfc6">Name</span> <span style="color:#b8bfc6">=</span> <span style="color:#d26b6b">"ww"</span>;
}
}
}</span></span>
2.3 使用 Prsim 模版构建项目
2.3.1 管理拓展

2.3.2 添加拓展(Prism 模版)

2.3.3 先关闭 VS,再安装


2.3.4 创建 Prism 模版项目
-
项目名不要以数字开头。


3. 区域(Region)
3.1 介绍
Prism框架中Region可以理解为一个UI容器,这些容器可以动态加载和卸载不同的视图和组件。
Region区域通常是一个控件,比如ContentControl、ItemsControl、TabControl。
可以理解为Region它就像是一个占位符,可以动态地向这个占位符中注入或者移除视图。
3.2 注册区域

示例代码中 Header 和 Content 使用region进行区域处理。
1. MainWindow.xaml
<span style="background-color:#333333"><span style="color:#b8bfc6"><span style="color:#999977"><</span><span style="color:#7df46a">Window</span> <span style="color:#7575e4">x:Class</span>=<span style="color:#d26b6b">"Prism_BlankApp1.Views.MainWindow"</span>
<span style="color:#7575e4">xmlns</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>
<span style="color:#7575e4">xmlns:x</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml"</span>
<span style="color:#7575e4">xmlns:prism</span>=<span style="color:#d26b6b">"http://prismlibrary.com/"</span>
<span style="color:#7575e4">prism:ViewModelLocator.AutoWireViewModel</span>=<span style="color:#d26b6b">"True"</span>
<span style="color:#7575e4">Title</span>=<span style="color:#d26b6b">"{Binding Title}"</span> <span style="color:#7575e4">Height</span>=<span style="color:#d26b6b">"350"</span> <span style="color:#7575e4">Width</span>=<span style="color:#d26b6b">"525"</span> <span style="color:#999977">></span>
<span style="color:#999977"><</span><span style="color:#7df46a">Grid</span><span style="color:#999977">></span>
<span style="color:#999977"><</span><span style="color:#7df46a">Grid.RowDefinitions</span><span style="color:#999977">></span>
<span style="color:#999977"><</span><span style="color:#7df46a">RowDefinition</span><span style="color:#999977">/></span>
<span style="color:#999977"><</span><span style="color:#7df46a">RowDefinition</span> <span style="color:#7575e4">Height</span>=<span style="color:#d26b6b">"5*"</span><span style="color:#999977">/></span>
<span style="color:#999977"></</span><span style="color:#7df46a">Grid.RowDefinitions</span><span style="color:#999977">></span>
<span style="color:#999977"><</span><span style="color:#7df46a">Grid.ColumnDefinitions</span><span style="color:#999977">></span>
<span style="color:#999977"><</span><span style="color:#7df46a">ColumnDefinition</span><span style="color:#999977">/></span>
<span style="color:#999977"><</span><span style="color:#7df46a">ColumnDefinition</span> <span style="color:#7575e4">Width</span>=<span style="color:#d26b6b">"3*"</span><span style="color:#999977">/></span>
<span style="color:#999977"></</span><span style="color:#7df46a">Grid.ColumnDefinitions</span><span style="color:#999977">></span>
<span style="color:#999977"><</span><span style="color:#7df46a">ContentControl</span> <span style="color:#7575e4">Grid.ColumnSpan</span>=<span style="color:#d26b6b">"2"</span> <span style="color:#7575e4">prism:RegionManager.RegionName</span>=<span style="color:#d26b6b">"HeaderRegion"</span><span style="color:#999977">/></span>
<span style="color:#999977"><</span><span style="color:#7df46a">StackPanel</span> <span style="color:#7575e4">Grid.Row</span>=<span style="color:#d26b6b">"1"</span> <span style="color:#7575e4">Background</span>=<span style="color:#d26b6b">"Aquamarine"</span><span style="color:#999977">></span>
<span style="color:#999977"><</span><span style="color:#7df46a">Button</span> <span style="color:#7575e4">Content</span>=<span style="color:#d26b6b">"菜单1"</span><span style="color:#999977">/></span>
<span style="color:#999977"><</span><span style="color:#7df46a">Button</span> <span style="color:#7575e4">Content</span>=<span style="color:#d26b6b">"菜单2"</span><span style="color:#999977">/></span>
<span style="color:#999977"></</span><span style="color:#7df46a">StackPanel</span><span style="color:#999977">></span>
<span style="color:#999977"><</span><span style="color:#7df46a">ContentControl</span> <span style="color:#7575e4">Grid.Row</span>=<span style="color:#d26b6b">"1"</span> <span style="color:#7575e4">Grid.Column</span>=<span style="color:#d26b6b">"1"</span> <span style="color:#7575e4">prism:RegionManager.RegionName</span>=<span style="color:#d26b6b">"ContentRegion"</span><span style="color:#999977">/></span>
<span style="color:#999977"></</span><span style="color:#7df46a">Grid</span><span style="color:#999977">></span>
<span style="color:#999977"></</span><span style="color:#7df46a">Window</span><span style="color:#999977">></span></span></span>
2. HeaderControl.xaml
<span style="background-color:#333333"><span style="color:#b8bfc6"><span style="color:#999977"><</span><span style="color:#7df46a">UserControl</span> <span style="color:#7575e4">x:Class</span>=<span style="color:#d26b6b">"Prism_BlankApp1.Views.HeaderControl"</span>
<span style="color:#7575e4">xmlns</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>
<span style="color:#7575e4">xmlns:x</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml"</span>
<span style="color:#7575e4">xmlns:mc</span>=<span style="color:#d26b6b">"http://schemas.openxmlformats.org/markup-compatibility/2006"</span>
<span style="color:#7575e4">xmlns:d</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/expression/blend/2008"</span>
<span style="color:#7575e4">xmlns:local</span>=<span style="color:#d26b6b">"clr-namespace:Prism_BlankApp1.Views"</span>
<span style="color:#7575e4">mc:Ignorable</span>=<span style="color:#d26b6b">"d"</span>
<span style="color:#7575e4">d:DesignHeight</span>=<span style="color:#d26b6b">"450"</span> <span style="color:#7575e4">d:DesignWidth</span>=<span style="color:#d26b6b">"800"</span><span style="color:#999977">></span>
<span style="color:#999977"><</span><span style="color:#7df46a">Grid</span> <span style="color:#7575e4">Background</span>=<span style="color:#d26b6b">"AliceBlue"</span><span style="color:#999977">></span>
<span style="color:#999977"><</span><span style="color:#7df46a">TextBlock</span> <span style="color:#7575e4">Text</span>=<span style="color:#d26b6b">"Header"</span> <span style="color:#7575e4">FontSize</span>=<span style="color:#d26b6b">"15"</span><span style="color:#999977">/></span>
<span style="color:#999977"></</span><span style="color:#7df46a">Grid</span><span style="color:#999977">></span>
<span style="color:#999977"></</span><span style="color:#7df46a">UserControl</span><span style="color:#999977">></span></span></span>
3. ContentControl.xaml
<span style="background-color:#333333"><span style="color:#b8bfc6"><UserControl x:Class="Prism_BlankApp1.Views.ContentControlMain"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Prism_BlankApp1.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="DarkKhaki">
<TextBlock Text="Content" FontSize="15"/>
</Grid>
</UserControl></span></span>
4. App.xaml.cs
<span style="background-color:#333333"><span style="color:#b8bfc6">namespace Prism_BlankApp1
{
public partial class App
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
//注册region控件
containerRegistry.Register<HeaderControl>();
containerRegistry.Register<ContentControl>();
}
}
}</span></span>
5. MainWindowViewModel.cs
<span style="background-color:#333333"><span style="color:#b8bfc6">namespace Prism_BlankApp1.ViewModels
{
public class MainWindowViewModel : BindableBase
{
private string _title = "Prism Application";
public string Title
{
get { return _title; }
set { SetProperty(ref _title, value); }
}
private IRegionManager _regionManager;
//MainWindowViewModel被创建时,会自动将 regionManager 传入
public MainWindowViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
//将视图注册到对应的region中
_regionManager.RegisterViewWithRegion("HeaderRegion", nameof(HeaderControl));
_regionManager.RegisterViewWithRegion("ContentRegion", nameof(ContentControl));
RegisterViewForRegion();
}
}</span></span>
4. 导航(Navigation)
4.1 介绍
可以实现应用程序中页面之间的导航和传递参数,简化应用程序的开发和维护。
4.2 注册导航
1. MenuControl.xaml
<span style="background-color:#333333"><span style="color:#b8bfc6"><Window x:Class="Prism_BlankApp1.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
Title="{Binding Title}" Height="350" Width="525" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="5*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<ContentControl Grid.ColumnSpan="2" prism:RegionManager.RegionName="HeaderRegion"/>
<StackPanel Grid.Row="1" Background="Aquamarine">
<Button Content="菜单1" Command="{Binding NavigateCommand}" CommandParameter="UserControl1"/>
<Button Content="菜单2" Command="{Binding NavigateCommand}" CommandParameter="UserControl2"/>
</StackPanel>
<ContentControl Grid.Row="1" Grid.Column="1" prism:RegionManager.RegionName="ContentRegion"/>
</Grid>
</Window></span></span>
2. UserControl1.xaml
<span style="background-color:#333333"><span style="color:#b8bfc6"><UserControl x:Class="Prism_BlankApp1.Views.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BlankApp1.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<StackPanel Background="Azure">
<TextBlock Text="页面1"/>
</StackPanel>
</UserControl></span></span>
3. UserControl2.xaml
<span style="background-color:#333333"><span style="color:#b8bfc6"><UserControl x:Class="Prism_BlankApp1.Views.UserControl2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BlankApp1.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="Bisque">
<TextBlock Text="页面2"/>
</Grid>
</UserControl></span></span>
4. App.xaml.cs
<span style="background-color:#333333"><span style="color:#b8bfc6">namespace Prism_BlankApp1
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
//注册region控件
containerRegistry.Register<HeaderControl>();
containerRegistry.Register<ContentControlMain>();
//注册导航控件
containerRegistry.RegisterForNavigation<UserControl1>();
containerRegistry.RegisterForNavigation<UserControl2>();
}
}
}</span></span>
5. MainWindowViewModel.cs
<span style="background-color:#333333"><span style="color:#b8bfc6">namespace Prism_BlankApp1.ViewModels
{
public class MainWindowViewModel : BindableBase
{
private string _title = "Prism Application";
public string Title
{
get { return _title; }
set { SetProperty(ref _title, value); }
}
public DelegateCommand<string> NavigateCommand { get; set; }
private IRegionManager _regionManager;
public MainWindowViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
//将视图注册到对应的region中
_regionManager.RegisterViewWithRegion("HeaderRegion", nameof(HeaderControl));
_regionManager.RegisterViewWithRegion("ContentRegion", nameof(ContentControl));
NavigateCommand = new DelegateCommand<string>(Navigate);
}
private void Navigate(string pageName)
{
_regionManager.RequestNavigate("ContentRegion", pageName);
}
}
}</span></span>
4.3 传递参数
1. MenuControlViewModel.cs
<span style="background-color:#333333"><span style="color:#b8bfc6">namespace Prism_BlankApp1.ViewModels
{
public class MenuControlViewModel
{
public DelegateCommand<string> NavigateCommand { get; set; }
private IRegionManager _regionManager;
public MenuControlViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
NavigateCommand = new DelegateCommand<string>(Navigate);
}
private void Navigate(string pageName)
{
NavigationParameters pairs = new NavigationParameters();
pairs.Add("msg", "数据");
_regionManager.RequestNavigate("ContentRegion", pageName, pairs);
}
}
}</span></span>
2. UserControl1ViewModel.cs
导航的目标视图需要通过实现
INavigationAware接口来实现,一般在目标视图的视图模型继承自INavigaionAware接口来实现其对应的方法。
<span style="background-color:#333333"><span style="color:#b8bfc6">namespace Prism_BlankApp1.ViewModels
{
public class UserControl1ViewModel : BindableBase, INavigationAware
{
private string _msg;
public string Msg
{
get { return _msg; }
set { SetProperty(ref _msg, value); }
}
private IRegionManager _regionManager;
public UserControl1ViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
}
public bool IsNavigationTarget(NavigationContext navigationContext) => true;
public void OnNavigatedFrom(NavigationContext navigationContext)
{
}
public void OnNavigatedTo(NavigationContext navigationContext)
{
NavigationParameters parameters = navigationContext.Parameters;
Msg = parameters["msg"].ToString();
}
}
}</span></span>
3. UserControl1.xaml
<span style="background-color:#333333"><span style="color:#b8bfc6"><UserControl x:Class="Prism_BlankApp1.Views.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BlankApp1.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<StackPanel Background="Azure">
<TextBlock Text="页面1"/>
<TextBlock Text="{Binding Msg}"/>
</StackPanel>
</UserControl></span></span>
4.4 导航日志
Prism的导航日志INavigationJournal的管理是自动运行的,其中包括记录成功的导航日志。而NavigationCallback是用来检测导航结果检查的,可以在这里根据导航成功或者失败做一些特殊处理。
1. MainWindow.xaml
<span style="background-color:#333333"><span style="color:#b8bfc6"><Window x:Class="Prism_BlankApp1.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
Title="{Binding Title}" Height="350" Width="525" >
<Window.Resources>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding DataContext.Head}"/>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="auto"/>
<RowDefinition Height="5*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<ContentControl Grid.ColumnSpan="2" prism:RegionManager.RegionName="HeaderRegion"/>
<StackPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal">
<Button Content="后退" Command="{Binding HistoryCommand}" CommandParameter="back"/>
<Button Content="前进" Command="{Binding HistoryCommand}" CommandParameter="next"/>
</StackPanel>
<StackPanel Grid.RowSpan="2" Grid.Row="1" Background="Aquamarine">
<Button Content="菜单1" Command="{Binding NavigateCommand}" CommandParameter="UserControl1"/>
<Button Content="菜单2" Command="{Binding NavigateCommand}" CommandParameter="UserControl2"/>
</StackPanel>
<ContentControl Grid.Row="2" Grid.Column="1" prism:RegionManager.RegionName="ContentRegion"/>
</Grid>
</Window></span></span>
2. MenuControlViewModel.cs
<span style="background-color:#333333"><span style="color:#b8bfc6">namespace Prism_BlankApp1.ViewModels
{
public class MainWindowViewModel : BindableBase
{
private string _title = "Prism Application";
public string Title
{
get { return _title; }
set { SetProperty(ref _title, value); }
}
public DelegateCommand<string> NavigateCommand { get; set; }
public DelegateCommand<string> HistoryCommand { get; set; }
private IRegionManager _regionManager;
private IRegionNavigationJournal _journal;
public MainWindowViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
_regionManager.RegisterViewWithRegion("HeaderRegion", nameof(HeaderControl));
_regionManager.RegisterViewWithRegion("ContentRegion", nameof(ContentControl));
NavigateCommand = new DelegateCommand<string>(Navigate);
HistoryCommand = new DelegateCommand<string>(History);
}
private void Navigate(string pageName)
{
NavigationParameters pairs = new NavigationParameters();
pairs.Add("msg", "数据");
_regionManager.RequestNavigate("ContentRegion", pageName, NavigateComplete, pairs);
}
private void NavigateComplete(NavigationResult navigationResult)
{
if (navigationResult.Result == true)
{
_journal = navigationResult.Context.NavigationService.Journal;
}
}
public void History(string msg)
{
if (_journal != null)
{
switch (msg)
{
case "back":
if (_journal.CanGoBack)
{
_journal.GoBack();
}
break;
case "next":
if (_journal.CanGoForward)
{
_journal.GoForward();
}
break;
}
}
}
}
}</span></span>
5. 事件聚合器(EventAggregato)
5.1 介绍
事件聚合器是一种实现组件间松耦合通信的模式,不需要知道事件的发布者和订阅者是谁,从而减少组件间的依赖关系。
事件聚合器是一个设计模式,允许多个对象或组件通过中心化的事件管理系统进行通信,这个中心化的系统被称为事件聚合器。
5.2 通信
1. UserControl1.xaml
<span style="background-color:#333333"><span style="color:#b8bfc6"><UserControl x:Class="BlankApp1.Views.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BlankApp1.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<StackPanel Background="Bisque">
<TextBlock Text="UserControl1"/>
<Button Content="修改数据" Width="200" Command="{Binding UpdateDataCommand}"/>
</StackPanel>
</UserControl></span></span>
2. UserControl1ViewModel.xaml.cs
<span style="background-color:#333333"><span style="color:#b8bfc6">namespace BlankApp1.ViewModels
{
public class UserControl1ViewModel
{
public class MyEvent : PubSubEvent<string> { }
public DelegateCommand UpdateDataCommand { get; set; }
private IRegionManager _regionManager;
private IEventAggregator _eventAggregator;
public UserControl1ViewModel(IRegionManager regionManager, IEventAggregator eventAggregator)
{
_regionManager = regionManager;
_eventAggregator = eventAggregator;
UpdateDataCommand = new DelegateCommand(ToUpdate);
}
private void ToUpdate()
{
_regionManager.RequestNavigate("ContentRegion", nameof(UserControl2));
_eventAggregator.GetEvent<MyEvent>().Publish("要修改的数据");
}
}
}</span></span>
3. UserControl2.xaml
<span style="background-color:#333333"><span style="color:#b8bfc6"><UserControl x:Class="BlankApp1.Views.UserControl2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BlankApp1.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="Pink">
<TextBlock Text="{Binding Data}" FontSize="15"/>
</Grid>
</UserControl></span></span>
4. UserControl2ViewModel.xaml.cs
<span style="background-color:#333333"><span style="color:#b8bfc6">{
public class UserControl2ViewModel:BindableBase
{
private string _data;
public string Data
{
get { return _data; }
set { SetProperty(ref _data, value); }
}
public UserControl2ViewModel(IEventAggregator eventAggregator)
{
eventAggregator.GetEvent<MyEvent>().Subscribe(GetValue);
}
private void GetValue(string data)
{
Data = data;
}
}
}</span></span>
6. 模块化(Module)
5.1 介绍
Prism框架支持将应用程序拆分为多个模块,每个模块具有自己的视图和视图模型。这种模块化的设计使得应用程序更加灵活和可扩展。
5.2 演示
1. 创建 Prism 模块项目

2. 项目结构

3. Module1Module.cs
<span style="background-color:#333333"><span style="color:#b8bfc6">namespace Module1
{
public class Module1Module: IModule
{
public void OnInitialized(IContainerProvider containerProvider)
{
//注册非导航控件
var regionManager = containerProvider.Resolve<RegionManager>();
regionManager.RegisterViewWithRegion("ContentRegion", typeof(ContentControl));
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
//注册导航控件
containerRegistry.RegisterForNavigation<UserControl1>();
containerRegistry.RegisterForNavigation<UserControl2>();
containerRegistry.RegisterForNavigation<UserControl3>();
}
}
}</span></span>
4. App.xaml.cs
<span style="background-color:#333333"><span style="color:#b8bfc6">namespace BlankApp1
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<HeaderControl>();
//containerRegistry.Register<ContentControl>();
//containerRegistry.RegisterForNavigation<UserControl1>();
//containerRegistry.RegisterForNavigation<UserControl2>();
//containerRegistry.RegisterForNavigation<UserControl3>();
}
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
base.ConfigureModuleCatalog(moduleCatalog);
moduleCatalog.AddModule<Module1Module>();
}
}
}</span></span>
5.3 区域和模块化总结
-
区域:将一个view中的内容拆分到不同的view当中。
-
模块化:将一个项目中的 Models Views ViewModels 拆分到不同的模块中。

419

被折叠的 条评论
为什么被折叠?



