Prism中如何不打开MainWindow完成Module Catalog创建与类型注册
实现方案
PrismApplication 的默认启动流程会在 OnStartup 中依次执行初始化容器、注册服务、创建模块目录,之后才会调用 CreateShell 创建并显示主窗口,你只需要手动触发前置的初始化逻辑,跳过Shell创建步骤即可,具体实现如下:
步骤1:在App类中新增公开初始化方法
在你继承自PrismApplication的App类中新增公开方法,仅执行Prism核心初始化,不触发主窗口创建:
public partial class App : PrismApplication { // 可选:暴露单例实例方便后续调用 public new static App Current => (App)Application.Current; // 可选:暴露容器供外部解析服务/窗口 public IContainerProvider ContainerProvider => Container; protected override Window CreateShell() { return Container.Resolve<MainWindow>(); } protected override void RegisterTypes(IContainerRegistry containerRegistry) { // 你的服务注册逻辑 } protected override IModuleCatalog CreateModuleCatalog() { // 你的模块目录创建逻辑 return new ModuleCatalog(); } // 新增无窗口初始化方法 public void InitializeWithoutShell() { // 加载App.xaml中定义的全局资源 InitializeComponent(); // 执行Prism核心初始化:自动触发CreateModuleCatalog、RegisterTypes、模块初始化 base.Initialize(); } }
步骤2:在应用启动阶段调用初始化方法
在DLL的初始化逻辑中调用上面新增的方法,不要调用默认的Run()方法即可:
// 保证全局仅初始化一次WPF应用实例 if (Application.Current == null) { var wpfApp = new App(); wpfApp.InitializeWithoutShell(); // 注意:不要执行wpfApp.Run(),否则会启动完整WPF消息循环阻塞线程,且触发主窗口创建 }
步骤3:需要时打开WPF窗口
后续点击自定义按钮需要打开WPF窗体时,直接从Prism容器解析主窗口实例显示即可:
var mainWindow = App.Current.ContainerProvider.Resolve<MainWindow>(); // 模态打开会自动处理WPF消息循环,非模态打开如果宿主是非WPF程序需要额外处理调度器 mainWindow.ShowDialog();
注意事项
- WPF应用实例全局只能存在一个,所以初始化前一定要判断
Application.Current是否为空,避免重复创建报错 - 初始化WPF实例的线程必须是STA线程,否则会触发WPF线程模型异常
- 如果宿主程序是非WPF程序(比如WinForm、Win32程序),非模态打开WPF窗口时需要手动启动WPF调度器处理消息
内容的提问来源于stack exchange,提问作者alexei.sorokin
相关产品推荐
相关产品推荐

