Prism 框架笔记及实例
一、Prism 框架概述
1. 概念
Prism 是一个跨平台的开源框架,用于在 WPF、Xamarin Form、Uno 平台和 WinUI 中构建松散耦合、可维护和可测试的 XAML 应用程序,支持 MVVM 设计模式,由微软官方团队最初开发,现属于.NET 基金会。
2. 发展历史
-
最初由 Microsoft Patterns & Practices 团队构建
-
旨在简化 WPF 应用程序的设计、编写、维护和扩展
-
现为.NET 基金会下的开源项目,经过财富 100 强等公司多年实践验证
二、Prism 核心功能
1. 核心组件
| 组件 | 说明 |
|---|---|
| Region (区域管理) | 替代传统的<Frame>和<ContentControl>,用于放置页面或用户控件 |
| View Injection (视图注入) | 基于 IOC 容器实现视图与 ViewModel 解耦,可在 VM 中依赖注入对象 |
| ViewModelLocationProvider (视图模型定位) | 自动关联视图与 ViewModel(需遵循约定) |
| Command (命令) | 提供DelegateCommand和DelegateCommand<T>,类似其他框架的RelayCommand |
| Navigation (导航) | 配合区域管理实现页面跳转 |
| Dialog (对话框) | 提供对话框服务,可将用户控件以对话框形式展示 |
| Module (模块) | 支持模块化开发,适用于大型项目 |
| Event Aggregator (事件聚合器) | 实现组件间通信,类似 WeakMessager/StrongMessager |
三、Prism 使用步骤
1. 环境准备
-
安装 Prism 模板:在 VS 的 "扩展 - 管理扩展" 中搜索 "Prism Template Pack"
-
项目模板选择:
-
Prism Full App:包含核心项目、模块、服务和单元测试
-
Prism Blank App:空白模板
-
Prism Module:模块模板
-
2. 普通 WPF 项目改造为 Prism 项目
(1)安装 NuGet 包
Install-Package Prism.DryIoc # 推荐使用DryIoc容器
(2)修改 App.xaml
<prism:PrismApplication x:Class="PrismDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/">
<!-- 移除StartupUri属性 -->
</prism:PrismApplication>
(3)修改 App.xaml.cs
using Prism.Ioc;
using System.Windows;
namespace PrismDemo
{
public partial class App : PrismApplication
{
// 创建主窗口
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
// 注册服务和视图
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// 注册导航视图
containerRegistry.RegisterForNavigation<PageA, PageAViewModel>();
containerRegistry.RegisterForNavigation<PageB>();
}
}
}
四、MVVM 实现核心
1. 基础类与方法
| Prism 组件 | 对应其他框架组件 | 说明 |
|---|---|---|
BindableBase |
ObservableObject(CommunityToolkit) |
实现INotifyPropertyChanged的基类 |
SetProperty() |
SetProperty()(CommunityToolkit) |
属性变更通知的简化方法 |
DelegateCommand |
RelayCommand(CommunityToolkit) |
命令实现类 |
2. 自动绑定 ViewModel(约定)
需满足 3 个条件:
-
视图(Window/UserControl/Page)放在
Views文件夹 -
视图模型放在
ViewModels文件夹 -
视图模型名称格式:
视图名称+ViewModel(如MainWindow对应MainWindowViewModel)
示例结构:
PrismDemo/
├─ Views/
│ ├─ MainWindow.xaml
│ └─ PageA.xaml
└─ ViewModels/
├─ MainWindowViewModel.cs
└─ PageAViewModel.cs
手动绑定(非约定场景):
在 XAML 中添加:
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
五、区域管理(Region)实例
1. 定义区域容器(XAML)
<!-- MainWindow.xaml -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- 导航按钮 -->
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Button Content="PageA" Command="{Binding NavigateCommand}" CommandParameter="PageA"/>
<Button Content="PageB" Command="{Binding NavigateCommand}" CommandParameter="PageB"/>
</StackPanel>
<!-- 区域容器 -->
<ContentControl Grid.Row="1" prism:RegionManager.RegionName="ContentRegion"/>
</Grid>
2. 视图模型中实现导航(ViewModel)
// MainWindowViewModel.cs
using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
namespace PrismDemo.ViewModels
{
public class MainWindowViewModel : BindableBase
{
private readonly IRegionManager _regionManager;
// 导航命令
public DelegateCommand<string> NavigateCommand { get; private set; }
public MainWindowViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
NavigateCommand = new DelegateCommand<string>(Navigate);
}
// 导航方法
private void Navigate(string viewName)
{
// 向区域请求导航
_regionManager.RequestNavigate("ContentRegion", viewName);
}
}
}
3. 注册视图(App.xaml.cs)
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// 注册视图到IOC容器(支持导航)
containerRegistry.RegisterForNavigation<Views.PageA, ViewModels.PageAViewModel>();
containerRegistry.RegisterForNavigation<Views.PageB>(); // 自动匹配PageBViewModel
}
六、区域适配器
1. 概念
区域适配器是连接控件与区域的桥梁,使控件能作为区域容器承载其他视图,基类为RegionAdapterBase<T>。
2. 内置适配器
| 适配器 | 支持的控件 |
|---|---|
ContentControlRegionAdapter |
<ContentControl> |
ItemsControlRegionAdapter |
<ItemsControl> |
SelectorRegionAdapter |
<ComboBox>、<ListBox>、<TabControl>、<Ribbon> |
七、命令(DelegateCommand)实例
// PageAViewModel.cs
using Prism.Commands;
using Prism.Mvvm;
namespace PrismDemo.ViewModels
{
public class PageAViewModel : BindableBase
{
private string _message;
public string Message
{
get => _message;
set => SetProperty(ref _message, value); // 属性变更通知
}
// 无参数命令
public DelegateCommand ClickCommand { get; private set; }
// 带参数命令
public DelegateCommand<string> ParamCommand { get; private set; }
public PageAViewModel()
{
Message = "PageA";
ClickCommand = new DelegateCommand(OnClick);
ParamCommand = new DelegateCommand<string>(OnParamClick);
}
private void OnClick()
{
Message = "点击了按钮";
}
private void OnParamClick(string param)
{
Message = $"参数:{param}";
}
}
}
XAML 绑定:
<!-- PageA.xaml -->
<StackPanel>
<TextBlock Text="{Binding Message}"/>
<Button Content="点击" Command="{Binding ClickCommand}"/>
<Button Content="带参数" Command="{Binding ParamCommand}" CommandParameter="Hello"/>
</StackPanel>
总结
Prism 框架通过约定优于配置的方式,简化了 MVVM 模式的实现,核心优势在于区域管理、导航、模块化和依赖注入。使用时需注意:
-
遵循视图与 ViewModel 的命名和文件夹约定
-
注册视图到 IOC 容器才能支持导航
-
利用区域适配器扩展自定义控件的区域功能
通过 Prism 可构建松耦合、可扩展的大型 XAML 应用程序,适用于 WPF、移动端等多平台场景。