一、安装包
重要前提(踩坑总结)
你的项目是 .NET Framework 4.8,请遵守:
- 用 Prism 8.1.97,不要用 Prism 9.x(.NET Framework 上有已知强名称 Bug)
- 必须安装
Prism.DryIoc,它会自动带上DryIoc.dll 4.7.7.0 - 不要保留
StartupUri,Prism 用CreateShell()启动 - 装完包后检查引用,确认
DryIoc在引用列表里
安装prism8
Install-Package Prism.Wpf -Version 8.1.97
Install-Package Prism.DryIoc -Version 8.1.97
装完后检查:
解决方案资源管理器 → 引用 里必须有 DryIoc。


检查 --- 输出目录
生成一次项目后,打开 bin\Debug\,确认有 DryIoc.dll。
没有这个文件,运行一定会报错。
添加绑定重定向(防版本冲突)
XML
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="DryIoc" publicKeyToken="dfbf2bd50fcf7768" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.7.7.0" newVersion="4.7.7.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
项目属性设置
右键项目 PrismStudy → 属性 → 生成:
• 平台目标:Any CPU
• 取消勾选「首选 32 位」
二、改造 App 启动方式
Prism 应用不用 StartupUri,由 PrismApplication 接管启动。
修改 App.xaml
删除 StartupUri,改成:
XML
<prism:PrismApplication x:Class="PrismStudy.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/">
<Application.Resources>
</Application.Resources>
</prism:PrismApplication>
修改 App.xaml.cs
cs
using Prism.DryIoc;
using Prism.Ioc;
using System.Windows;
namespace PrismStudy
{
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// 暂时为空,第 3 课会注册 ViewModel
}
}
}
理解两个核心方法
| 方法 | 作用 |
|---|---|
CreateShell() |
创建并返回主窗口(Shell) |
RegisterTypes() |
向 DI 容器注册 View、ViewModel、Service |
验证
生成 → 重新生成解决方案,按 F5。
应弹出空的 MainWindow,无报错。
常见报错
| 报错 | 原因 | 解决 |
|---|---|---|
Prism.Container.Abstractions 强名称验证失败 |
装了 Prism 9 | 卸载,改用 8.1.97 |
DryIoc Version=4.7.7.0 不匹配 |
bin\Debug 没有 DryIoc.dll |
检查引用里是否有 DryIoc,重新生成 |
| 窗口闪退 | App.xaml 还留着 StartupUri |
删掉 StartupUri |
三、第一个 MVVM
步骤 1:创建文件夹
PrismStudy/
├── Views/ ← 放 XAML 视图
├── ViewModels/ ← 放 ViewModel
把 MainWindow.xaml 和 MainWindow.xaml.cs 拖到 Views 文件夹。
VS 会提示更新命名空间,选「是」。
步骤 2:创建 ViewModels/MainWindowViewModel.cs
cs
using Prism.Commands;
using Prism.Mvvm;
namespace PrismStudy.ViewModels
{
public class MainWindowViewModel : BindableBase
{
private string _title = "Prism 学习项目";
public string Title
{
get => _title;
set => SetProperty(ref _title, value);
}
private string _message = "点击按钮试试";
public string Message
{
get => _message;
set => SetProperty(ref _message, value);
}
public DelegateCommand ClickCommand { get; }
public MainWindowViewModel()
{
ClickCommand = new DelegateCommand(OnClick);
}
private void OnClick()
{
Message = "Hello Prism! 当前时间:" + System.DateTime.Now.ToString("HH:mm:ss");
}
}
}
步骤 3:修改 Views/MainWindow.xaml
XML
<Window x:Class="PrismStudy.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="450" Width="800">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="{Binding Message}" FontSize="20" Margin="0,0,0,20"/>
<Button Content="点击我" Command="{Binding ClickCommand}"
Width="120" Height="40"/>
</StackPanel>
</Window>
步骤 4:更新 App.xaml.cs
cs
using Prism.DryIoc;
using Prism.Ioc;
using System.Windows;
using PrismStudy.ViewModels;
using PrismStudy.Views;
namespace PrismStudy
{
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<MainWindowViewModel>();
}
}
}
关键概念:
| 概念 | 说明 |
|---|---|
BindableBase |
ViewModel 基类,SetProperty 触发 UI 更新 |
DelegateCommand |
把按钮点击绑定到方法 |
AutoWireViewModel="True" |
按命名约定自动关联:MainWindow → MainWindowViewModel |
验证
运行后点击按钮,文字变为带时间的 Hello Prism!。
踩坑:如果MainWindow和MainWindowViewModel的名字不是这个结构,那就可以不使用注册,而是使用导航。如果这两个的命名空间也不一样,也是使用的导航。
cs
//注册类型到主容器里
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<MainWindowViewModel>();//注册进容器
containerRegistry.RegisterForNavigation<MainWindow, MainWindowViewModel>();//注册+导航
}
四、Region 区域导航
大多用于子界面的切换。
目标
把 MainWindow 从单一页面改成 Shell 壳窗口:

步骤 1:创建 Views 文件夹和两个子页面
右键项目 → 添加 → 新建文件夹 → 命名为 Views
在 Views 下:添加 → 用户控件(WPF),创建 HomeView.xaml 和 SettingsView.xaml
XML
<UserControl x:Class="PrismStudy.Views.HomeView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TextBlock Text="这是首页" FontSize="24"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
</UserControl>
XML
<UserControl x:Class="PrismStudy.Views.SettingsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TextBlock Text="这是设置页" FontSize="24"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
</UserControl>
步骤 2:改造 MainWindow.xaml 为 Shell
用下面内容整体替换你现在的 MainWindow.xaml:
XML
<Window x:Class="PrismStudy.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="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- 左侧导航 -->
<StackPanel Grid.Column="0" Background="#F0F0F0">
<Button Content="首页" Command="{Binding NavigateCommand}"
CommandParameter="HomeView" Margin="10" Height="35"/>
<Button Content="设置" Command="{Binding NavigateCommand}"
CommandParameter="SettingsView" Margin="10" Height="35"/>
</StackPanel>
<!-- 右侧内容区(Region) -->
<ContentControl Grid.Column="1"
prism:RegionManager.RegionName="ContentRegion"/>
</Grid>
</Window>
CommandParameter 的值 "HomeView" / "SettingsView" 必须与后面 RegisterForNavigation 注册的名称一致(默认就是类名)。
步骤 3:改造 ViewModels/MainWindowViewModel.cs
用下面内容整体替换原来的点击按钮版本:
cs
using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
namespace PrismStudy.ViewModels
{
public class MainWindowViewModel : BindableBase
{
private readonly IRegionManager _regionManager;
public string Title { get; } = "Prism 区域导航演示";
public DelegateCommand<string> NavigateCommand { get; }
public MainWindowViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
NavigateCommand = new DelegateCommand<string>(Navigate);
}
//这个命令带有参数 界面按下按钮 点击不同的按钮 传不同的参数 然后切换对应的界面 ContentRegion 这个是主界面区域自己取得名字 指更换这个区域的显示内容
private void Navigate(string viewName)
{
_regionManager.RequestNavigate("ContentRegion", viewName);
}
}
}
步骤 4:更新 App.xaml.cs
在你现有注册的基础上追加子页面注册和默认导航:
cs
using Prism.DryIoc;
using Prism.Ioc;
using Prism.Regions;
using PrismStudy.ViewModels;
using PrismStudy.Views;
using System.Windows;
namespace PrismStudy
{
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// MainWindow 在根命名空间,必须显式关联 ViewModel(你第 3 课已验证)
containerRegistry.RegisterForNavigation<MainWindow, MainWindowViewModel>();
containerRegistry.RegisterForNavigation<HomeView>();//这里只写一个窗体是什么意思?
//「我有两个可以导航的页面:HomeView 和 SettingsView。以后有人要跳转时,请按这个名字去找并显示它们。」
containerRegistry.RegisterForNavigation<SettingsView>();//一般用作子页面跳转
}
protected override void OnInitialized()
{
base.OnInitialized();
// 启动时默认显示首页
var regionManager = Container.Resolve<IRegionManager>();
//这条代码是设置 名字叫做ContentRegion区域 初始显示的画面是HomeView
regionManager.RequestNavigate("ContentRegion", "HomeView");
}
}
}
第 4 课完成后,
Register<MainWindowViewModel>()可以删掉,只保留RegisterForNavigation<MainWindow, MainWindowViewModel>()就够了。
验证
- F5 运行,窗口标题为 「Prism 区域导航演示」
- 右侧默认显示 「这是首页」
- 点「设置」→ 显示 「这是设置页」
- 点「首页」→ 切回首页