WPF Prism 框架完全入门指南:从环境搭建到弹窗导航实战

WPF Prism 框架完全入门指南:从环境搭建到弹窗导航实战

    • 前言
    • [一、Prism 框架概述](#一、Prism 框架概述)
      • [1.1 什么是 Prism](#1.1 什么是 Prism)
      • [1.2 为什么选择 Prism](#1.2 为什么选择 Prism)
    • [二、环境搭建与第一个 Prism 应用](#二、环境搭建与第一个 Prism 应用)
      • [2.1 创建项目并安装 NuGet 包](#2.1 创建项目并安装 NuGet 包)
      • [2.2 改造 App.xaml](#2.2 改造 App.xaml)
      • [2.3 实现必要方法](#2.3 实现必要方法)
      • [2.4 项目结构约定](#2.4 项目结构约定)
    • [三、MVVM 模式在 Prism 中的实现](#三、MVVM 模式在 Prism 中的实现)
      • [3.1 BindableBase 与属性变更通知](#3.1 BindableBase 与属性变更通知)
      • [3.2 DelegateCommand 命令绑定](#3.2 DelegateCommand 命令绑定)
      • [3.3 ViewModelLocator 自动绑定](#3.3 ViewModelLocator 自动绑定)
    • 四、区域与导航系统
      • [4.1 区域(Region)概念](#4.1 区域(Region)概念)
      • [4.2 视图发现与视图注入](#4.2 视图发现与视图注入)
      • [4.3 基于 URI 的导航](#4.3 基于 URI 的导航)
      • [4.4 INavigationAware 接口](#4.4 INavigationAware 接口)
      • [4.5 导航日志](#4.5 导航日志)
    • 五、对话框服务
      • [5.1 传统弹窗的问题](#5.1 传统弹窗的问题)
      • [5.2 实现 IDialogAware 接口](#5.2 实现 IDialogAware 接口)
      • [5.3 注册与使用对话框](#5.3 注册与使用对话框)
      • [5.4 自定义对话框窗口样式](#5.4 自定义对话框窗口样式)
    • 六、完整示例:一个简单的员工管理系统
      • [6.1 项目结构](#6.1 项目结构)
      • [6.2 关键代码实现](#6.2 关键代码实现)
    • 七、最佳实践与注意事项
      • [7.1 服务生命周期管理](#7.1 服务生命周期管理)
      • [7.2 模块化开发建议](#7.2 模块化开发建议)
      • [7.3 注意事项](#7.3 注意事项)
    • 八、总结

前言

在 WPF 桌面应用开发中,随着项目规模的增长,如果没有良好的架构设计,代码很快就会变得难以维护------视图与逻辑紧密耦合、模块间相互依赖、测试困难等问题会接踵而至。Prism 正是为了解决这些问题而生的 MVVM 框架。

Prism 最初由微软 Patterns & Practices 团队开发,后转为开源社区维护,至今已有十余年历史。它提供了一套完整的设计模式实现,包括依赖注入、模块化、导航、事件聚合等核心功能,能够帮助开发者构建松耦合、可测试、可维护的 XAML 应用程序。

本文将从零开始,带你系统地掌握 Prism 的核心概念与实战技巧,涵盖环境搭建、MVVM 实现、区域导航、弹窗服务等日常开发中最常用的功能。

一、Prism 框架概述

1.1 什么是 Prism

Prism 是一个用于构建 XAML 应用的 MVVM 框架,支持 WPF、.NET MAUI、Uno Platform 和 Xamarin Forms 等平台。它的核心功能通过 .NET Standard 共享库实现,各平台特定的功能则在相应的库中实现。

Prism 主要提供以下能力:

  • MVVM 基础设施:BindableBase 基类、DelegateCommand 命令封装
  • 依赖注入:统一的 IContainerRegistry 接口,支持 Unity、DryIoc 等容器
  • 区域管理:将 UI 拆分为多个区域,实现视图的动态加载与切换
  • 模块化:将应用分解为独立模块,支持按需加载
  • 导航系统:基于 URI 的视图导航,支持参数传递与导航日志
  • 对话框服务:MVVM 模式下的弹窗解决方案
  • 事件聚合器:组件间松耦合的消息通信机制

1.2 为什么选择 Prism

相比 MVVM Light、Caliburn.Micro 等其他 MVVM 框架,Prism 的优势在于:

  1. 功能全面:不仅提供 MVVM 基础能力,还涵盖模块化、区域导航等企业级功能
  2. 生态成熟:微软官方背景,文档完善,社区活跃
  3. 容器无关:通过统一接口支持多种 IoC 容器
  4. 平台统一:核心逻辑可跨平台复用

二、环境搭建与第一个 Prism 应用

2.1 创建项目并安装 NuGet 包

首先,在 Visual Studio 中创建一个 WPF 应用程序项目(.NET 6/7/8 均可)。然后安装 Prism 相关的 NuGet 包。

Prism 支持多种 IoC 容器,常用的是 Unity 和 DryIoc,选择其一即可:

Package 容器 说明
Prism.Unity Unity 经典选择,下载量最高
Prism.DryIoc DryIoc 性能更优,轻量级

通过 NuGet 包管理器或程序包管理器控制台安装:

powershell 复制代码
Install-Package Prism.Unity

提示:安装 Prism.Unity 会自动引入 Prism.Core 和 Prism.Wpf,无需单独安装其他依赖。

2.2 改造 App.xaml

将标准 WPF 的 Application 类替换为 Prism 的 PrismApplication

App.xaml

xml 复制代码
<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:local="clr-namespace:PrismDemo"
    xmlns:prism="http://prismlibrary.com/">
    <Application.Resources>
    </Application.Resources>
</prism:PrismApplication>

注意 :务必删除 StartupUri 属性,否则会导致两个窗口实例被创建。

2.3 实现必要方法

App.xaml.cs

csharp 复制代码
using System.Windows;
using Prism.Ioc;
using Prism.Unity;
using PrismDemo.Views;

namespace PrismDemo
{
    public partial class App : PrismApplication
    {
        // 创建应用程序的主窗口(Shell)
        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }

        // 注册应用程序中使用的类型和服务
        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            // 这里暂时为空,后续会添加注册内容
        }
    }
}

CreateShell 方法通过 IoC 容器解析并返回主窗口实例,RegisterTypes 方法用于注册应用中的服务与依赖。至此,一个最简 Prism 应用已搭建完成。

2.4 项目结构约定

Prism 推荐(但不强制)以下目录结构:

复制代码
PrismDemo/
├── Views/           # 视图文件(Window、UserControl)
├── ViewModels/      # 视图模型文件
├── Models/          # 数据模型
├── Services/        # 服务接口与实现
└── Controls/        # 自定义控件

这种约定有助于 ViewModelLocator 自动匹配视图与视图模型。

三、MVVM 模式在 Prism 中的实现

3.1 BindableBase 与属性变更通知

Prism 提供了 BindableBase 作为 ViewModel 的基类,它实现了 INotifyPropertyChanged 接口,并提供了 SetProperty 方法简化属性变更通知:

csharp 复制代码
using Prism.Mvvm;
using System.Collections.ObjectModel;

namespace PrismDemo.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private string _title = "Prism Demo Application";
        public string Title
        {
            get => _title;
            set => SetProperty(ref _title, value);
        }

        private string _selectedItem;
        public string SelectedItem
        {
            get => _selectedItem;
            set
            {
                if (SetProperty(ref _selectedItem, value))
                {
                    // 当选中的项变化时执行的额外逻辑
                    OnSelectedItemChanged();
                }
            }
        }

        public ObservableCollection<string> Items { get; set; } = 
            new ObservableCollection<string>();
        
        private void OnSelectedItemChanged()
        {
            // 处理选中项变化
        }
    }
}

SetProperty 方法会检查新旧值是否相等,仅在值变化时触发 PropertyChanged 事件,并返回 bool 值指示是否发生了变化。

3.2 DelegateCommand 命令绑定

Prism 使用 DelegateCommand 实现 ICommand 接口,支持带参数和不带参数的命令,以及执行条件判断:

csharp 复制代码
using Prism.Commands;

public class MainWindowViewModel : BindableBase
{
    // 无参数命令
    private DelegateCommand _loadCommand;
    public DelegateCommand LoadCommand =>
        _loadCommand ?? (_loadCommand = new DelegateCommand(ExecuteLoad));

    // 带参数命令
    private DelegateCommand<string> _deleteCommand;
    public DelegateCommand<string> DeleteCommand =>
        _deleteCommand ?? (_deleteCommand = new DelegateCommand<string>(
            ExecuteDelete, CanExecuteDelete));

    // 可观察属性,用于触发 CanExecute 重新评估
    private bool _isLoading;
    public bool IsLoading
    {
        get => _isLoading;
        set => SetProperty(ref _isLoading, value);
    }

    private void ExecuteLoad()
    {
        IsLoading = true;
        // 执行加载逻辑...
        IsLoading = false;
    }

    private void ExecuteDelete(string parameter)
    {
        // 删除指定项
    }

    private bool CanExecuteDelete(string parameter)
    {
        return !string.IsNullOrEmpty(parameter) && !IsLoading;
    }

    // 观察命令:当指定属性变化时自动触发 CanExecuteChanged
    public MainWindowViewModel()
    {
        DeleteCommand.ObservesProperty(() => IsLoading);
    }
}

ObservesProperty 方法可以让命令自动监听属性变化,无需手动调用 RaiseCanExecuteChanged

3.3 ViewModelLocator 自动绑定

Prism 的 ViewModelLocator 通过约定自动将 View 与 ViewModel 关联,默认规则是:

  • Views 在 Views 命名空间,ViewModels 在 ViewModels 命名空间
  • MainWindowMainWindowViewModel
  • EmployeeViewEmployeeViewModel

这意味着你不需要 手动设置 DataContext,只需遵循命名约定即可。

如需手动控制或禁用自动绑定,可以在 View 的 XAML 中设置:

xml 复制代码
<Window x:Class="PrismDemo.Views.MyView"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="False">
    <!-- 手动设置 DataContext -->
</Window>

四、区域与导航系统

4.1 区域(Region)概念

区域是 Prism 中用于动态管理视图的核心概念。你可以将应用程序的 UI 划分为多个区域,每个区域作为视图的容器,在运行时动态加载不同的内容。

定义区域

xml 复制代码
<Window x:Class="PrismDemo.Views.MainWindow"
        xmlns:prism="http://prismlibrary.com/">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        
        <!-- 左侧导航区域 -->
        <ContentControl Grid.Column="0" 
                        prism:RegionManager.RegionName="NavigationRegion"/>
        
        <!-- 主内容区域 -->
        <ContentControl Grid.Column="1" 
                        prism:RegionManager.RegionName="ContentRegion"/>
    </Grid>
</Window>

常用的区域宿主控件:

  • ContentControl:显示单个视图
  • ItemsControl:显示多个视图
  • TabControl:以标签页形式显示视图

4.2 视图发现与视图注入

有两种方式将视图添加到区域中:

视图发现(View Discovery):在应用启动时自动将视图加载到区域

csharp 复制代码
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    // 自动将 NavigationView 加载到 NavigationRegion
    containerRegistry.RegisterForNavigation<NavigationView>();
    
    // 注册视图到指定区域(需要重写 ConfigureRegionAdapterMappings)
}

视图注入(View Injection):通过代码手动控制视图的创建和注入时机

csharp 复制代码
public class MainWindowViewModel : BindableBase
{
    private readonly IRegionManager _regionManager;
    
    public MainWindowViewModel(IRegionManager regionManager)
    {
        _regionManager = regionManager;
    }
    
    private void LoadNavigationView()
    {
        var navigationView = Container.Resolve<NavigationView>();
        IRegion region = _regionManager.Regions["NavigationRegion"];
        region.Add(navigationView);
    }
}

4.3 基于 URI 的导航

Prism 提供了更灵活的基于 URI 的导航机制,支持参数传递和导航回调:

注册导航视图

csharp 复制代码
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    // 注册可导航的视图
    containerRegistry.RegisterForNavigation<HomeView>("HomeView");
    containerRegistry.RegisterForNavigation<EmployeeListView>("EmployeeList");
    containerRegistry.RegisterForNavigation<EmployeeDetailView>("EmployeeDetail");
}

发起导航

csharp 复制代码
public class NavigationViewModel : BindableBase
{
    private readonly IRegionManager _regionManager;
    
    public DelegateCommand<string> NavigateCommand { get; }

    public NavigationViewModel(IRegionManager regionManager)
    {
        _regionManager = regionManager;
        NavigateCommand = new DelegateCommand<string>(ExecuteNavigate);
    }

    private void ExecuteNavigate(string viewName)
    {
        // 简单导航
        _regionManager.RequestNavigate("ContentRegion", viewName);
        
        // 带参数的导航
        var parameters = new NavigationParameters
        {
            { "id", 123 },
            { "mode", "edit" }
        };
        _regionManager.RequestNavigate("ContentRegion", viewName, parameters);
        
        // 带回调的导航
        _regionManager.RequestNavigate("ContentRegion", viewName, 
            result =>
            {
                if (result.Result == true)
                    StatusMessage = "导航成功";
                else
                    StatusMessage = $"导航失败: {result.Error?.Message}";
            });
    }
}

4.4 INavigationAware 接口

让 ViewModel 实现 INavigationAware 接口,可以在导航过程中接收参数、确认导航或取消导航:

csharp 复制代码
using Prism.Regions;

public class EmployeeDetailViewModel : BindableBase, INavigationAware
{
    private int _employeeId;
    
    // 导航到本页时调用
    public void OnNavigatedTo(NavigationContext navigationContext)
    {
        // 获取导航参数
        if (navigationContext.Parameters.ContainsKey("id"))
        {
            _employeeId = navigationContext.Parameters.GetValue<int>("id");
            LoadEmployeeData(_employeeId);
        }
    }

    // 是否可以导航到本页(可用于权限验证)
    public bool IsNavigationTarget(NavigationContext navigationContext)
    {
        var id = navigationContext.Parameters.GetValue<int>("id");
        return id > 0;
    }

    // 从本页离开时调用
    public void OnNavigatedFrom(NavigationContext navigationContext)
    {
        // 清理资源,或保存草稿
    }
}

4.5 导航日志

Prism 提供了导航日志功能,支持前进/后退操作:

csharp 复制代码
public class EmployeeDetailViewModel : BindableBase, INavigationAware
{
    private IRegionNavigationService _navigationService;
    
    public DelegateCommand GoBackCommand { get; }
    public DelegateCommand GoForwardCommand { get; }

    public EmployeeDetailViewModel()
    {
        GoBackCommand = new DelegateCommand(GoBack, CanGoBack);
        GoForwardCommand = new DelegateCommand(GoForward, CanGoForward);
    }

    public void OnNavigatedTo(NavigationContext navigationContext)
    {
        _navigationService = navigationContext.NavigationService;
        GoBackCommand.RaiseCanExecuteChanged();
    }

    private void GoBack()
    {
        if (_navigationService?.Journal.CanGoBack == true)
            _navigationService.Journal.GoBack();
    }

    private bool CanGoBack() => _navigationService?.Journal.CanGoBack ?? false;
    
    private void GoForward()
    {
        if (_navigationService?.Journal.CanGoForward == true)
            _navigationService.Journal.GoForward();
    }

    private bool CanGoForward() => _navigationService?.Journal.CanGoForward ?? false;
}

五、对话框服务

5.1 传统弹窗的问题

在 MVVM 模式中,直接在 ViewModel 里调用 MessageBox.Show() 会破坏视图与逻辑的分离,使单元测试变得困难。Prism 提供了 IDialogService 来解决这个问题,让弹窗操作完全在 MVVM 模式下进行。

5.2 实现 IDialogAware 接口

首先创建对话框的 View 和 ViewModel,ViewModel 需要实现 IDialogAware 接口:

MyDialog.xaml(UserControl):

xml 复制代码
<UserControl x:Class="PrismDemo.Views.MyDialog"
             xmlns:prism="http://prismlibrary.com/">
    <Grid Margin="20" MinWidth="300">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        
        <TextBlock Text="{Binding Title}" FontSize="16" FontWeight="Bold"/>
        
        <TextBox Grid.Row="1" Text="{Binding InputText, UpdateSourceTrigger=PropertyChanged}" 
                 Margin="0,15" Height="30"/>
        
        <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right">
            <Button Content="确定" Command="{Binding ConfirmCommand}" 
                    Width="80" Margin="5" Style="{StaticResource PrimaryButton}"/>
            <Button Content="取消" Command="{Binding CancelCommand}" 
                    Width="80" Margin="5"/>
        </StackPanel>
    </Grid>
</UserControl>

MyDialogViewModel.cs

csharp 复制代码
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;

namespace PrismDemo.ViewModels
{
    public class MyDialogViewModel : BindableBase, IDialogAware
    {
        #region IDialogAware 实现
        public string Title => "用户输入";

        public event Action<IDialogResult> RequestClose;

        public bool CanCloseDialog() => true;

        public void OnDialogClosed()
        {
            // 对话框关闭时的清理逻辑
        }

        public void OnDialogOpened(IDialogParameters parameters)
        {
            // 接收传入的参数
            if (parameters.ContainsKey("message"))
            {
                Message = parameters.GetValue<string>("message");
            }
            if (parameters.ContainsKey("defaultValue"))
            {
                InputText = parameters.GetValue<string>("defaultValue");
            }
        }
        #endregion

        #region 属性与命令
        private string _message;
        public string Message
        {
            get => _message;
            set => SetProperty(ref _message, value);
        }

        private string _inputText;
        public string InputText
        {
            get => _inputText;
            set => SetProperty(ref _inputText, value);
        }

        public DelegateCommand ConfirmCommand { get; }
        public DelegateCommand CancelCommand { get; }
        #endregion

        public MyDialogViewModel()
        {
            ConfirmCommand = new DelegateCommand(OnConfirm);
            CancelCommand = new DelegateCommand(OnCancel);
        }

        private void OnConfirm()
        {
            var parameters = new DialogParameters
            {
                { "result", InputText }
            };
            RequestClose?.Invoke(new DialogResult(ButtonResult.OK, parameters));
        }

        private void OnCancel()
        {
            RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel));
        }
    }
}

5.3 注册与使用对话框

注册对话框(在 App.xaml.cs 中):

csharp 复制代码
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    // 注册对话框
    containerRegistry.RegisterDialog<MyDialog, MyDialogViewModel>();
    
    // 可选:注册自定义对话框窗口样式
    // containerRegistry.RegisterDialogWindow<CustomDialogWindow>();
}

调用对话框

csharp 复制代码
public class MainWindowViewModel : BindableBase
{
    private readonly IDialogService _dialogService;
    
    public DelegateCommand OpenDialogCommand { get; }

    public MainWindowViewModel(IDialogService dialogService)
    {
        _dialogService = dialogService;
        OpenDialogCommand = new DelegateCommand(OpenDialog);
    }

    private void OpenDialog()
    {
        var parameters = new DialogParameters
        {
            { "message", "请输入您的姓名:" },
            { "defaultValue", "张三" }
        };

        _dialogService.ShowDialog("MyDialog", parameters, result =>
        {
            if (result.Result == ButtonResult.OK)
            {
                var userInput = result.Parameters.GetValue<string>("result");
                StatusMessage = $"您输入了:{userInput}";
            }
            else
            {
                StatusMessage = "用户取消了操作";
            }
        });
    }
}

5.4 自定义对话框窗口样式

如果不想使用 Prism 默认的对话框窗口,可以自定义窗口样式:

方式一:在 UserControl 中定义窗口样式

xml 复制代码
<UserControl x:Class="PrismDemo.Views.MyDialog"
             xmlns:prism="http://prismlibrary.com/">
    <prism:Dialog.WindowStyle>
        <Style TargetType="Window">
            <Setter Property="Width" Value="450"/>
            <Setter Property="Height" Value="300"/>
            <Setter Property="ResizeMode" Value="NoResize"/>
            <Setter Property="WindowStartupLocation" Value="CenterOwner"/>
            <Setter Property="WindowStyle" Value="None"/>
            <Setter Property="AllowsTransparency" Value="True"/>
            <Setter Property="Background" Value="Transparent"/>
        </Style>
    </prism:Dialog.WindowStyle>
    <!-- 对话框内容 -->
</UserControl>

方式二:创建自定义窗口并注册

csharp 复制代码
// CustomDialogWindow.xaml.cs
public partial class CustomDialogWindow : Window, IDialogWindow
{
    public IDialogResult Result { get; set; }
    
    public CustomDialogWindow()
    {
        InitializeComponent();
    }
}

// App.xaml.cs
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    containerRegistry.RegisterDialogWindow<CustomDialogWindow>();
}

六、完整示例:一个简单的员工管理系统

下面通过一个完整示例串联上述知识点,实现一个具备导航、弹窗、数据绑定功能的简易员工管理系统。

6.1 项目结构

复制代码
EmployeeManager/
├── App.xaml / App.xaml.cs
├── Views/
│   ├── MainWindow.xaml
│   ├── EmployeeListView.xaml
│   ├── EmployeeDetailView.xaml
│   └── ConfirmDialog.xaml
├── ViewModels/
│   ├── MainWindowViewModel.cs
│   ├── EmployeeListViewModel.cs
│   ├── EmployeeDetailViewModel.cs
│   └── ConfirmDialogViewModel.cs
├── Models/
│   └── Employee.cs
└── Services/
    ├── IEmployeeService.cs
    └── EmployeeService.cs

6.2 关键代码实现

MainWindow.xaml

xml 复制代码
<Window x:Class="EmployeeManager.Views.MainWindow"
        xmlns:prism="http://prismlibrary.com/"
        Title="{Binding Title}" Height="500" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        
        <!-- 工具栏 -->
        <StackPanel Orientation="Horizontal" Margin="10">
            <Button Content="员工列表" Command="{Binding NavigateCommand}" 
                    CommandParameter="EmployeeListView" Margin="5"/>
            <Button Content="新增员工" Command="{Binding AddEmployeeCommand}" Margin="5"/>
        </StackPanel>
        
        <!-- 主内容区域 -->
        <ContentControl Grid.Row="1" 
                        prism:RegionManager.RegionName="ContentRegion"/>
    </Grid>
</Window>

App.xaml.cs 注册配置

csharp 复制代码
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    // 注册服务
    containerRegistry.RegisterSingleton<IEmployeeService, EmployeeService>();
    
    // 注册导航视图
    containerRegistry.RegisterForNavigation<EmployeeListView>();
    containerRegistry.RegisterForNavigation<EmployeeDetailView>();
    
    // 注册对话框
    containerRegistry.RegisterDialog<ConfirmDialog, ConfirmDialogViewModel>();
}

七、最佳实践与注意事项

7.1 服务生命周期管理

Prism 提供了多种服务注册方式,应根据场景选择合适的生命周期:

csharp 复制代码
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    // 瞬时:每次解析都创建新实例
    containerRegistry.Register<IService, ServiceImplementation>();
    
    // 单例:全局唯一实例
    containerRegistry.RegisterSingleton<IConfigService, ConfigService>();
    
    // 实例注册:注册已创建的实例
    var logger = new LogService();
    containerRegistry.RegisterInstance<ILogService>(logger);
}

7.2 模块化开发建议

对于大型项目,建议采用模块化架构:

  • 每个业务模块独立为一个类库项目
  • 模块实现 IModule 接口,在 OnInitialized 中注册模块内的视图和服务
  • 通过 ModuleCatalog 配置模块加载方式(代码、目录扫描、配置文件)

7.3 注意事项

  1. 命名约定:严格遵循 Views/ViewModels 的命名约定,可避免手动配置 ViewModelLocator
  2. 内存管理 :实现 IDisposable 并在 OnNavigatedFrom 中清理事件订阅
  3. UI 线程 :属性变更会自动跨线程处理,但耗时操作仍需使用 Task.Run
  4. 对话框结果 :不要在 OnDialogClosed 中调用 RequestClose,此时事件已为 null

八、总结

Prism 为 WPF 开发提供了完整的 MVVM 基础设施,其核心优势在于:

  1. 关注点分离:通过 ViewModelLocator、数据绑定和命令,彻底分离视图与逻辑
  2. 松耦合通信:EventAggregator 和 DialogService 实现组件间的低耦合交互
  3. 灵活的导航:基于区域的导航系统支持复杂的页面流转和参数传递
  4. 可测试性:依赖注入和接口抽象使单元测试变得简单

本文覆盖了 Prism 的核心功能,包括环境搭建、MVVM 基础、区域导航和对话框服务。掌握这些内容后,你已经能够使用 Prism 开发结构清晰、易于维护的 WPF 企业级应用。

建议进一步阅读 Prism 官方文档GitHub 示例项目,深入了解事件聚合器、模块化等高级特性。

相关推荐
雨浓YN4 小时前
WPF MVVM 模式(无调库)项目创建笔记
笔记·wpf
周杰伦fans15 小时前
.NET AOT技术深度解析:为什么WPF不支持而Avalonia/UWP支持?
.net·wpf
雨浓YN15 小时前
WPF MVVM 模式(调Prism库)项目创建笔记 —— 包含C++/CLI OpenCV互操作
c++·笔记·wpf
七夜zippoe15 小时前
DolphinDB数据模型:表、分区与分布式表
分布式·wpf·数据模型··dolphindb
一念春风1 天前
Qwen2.5 (AI模型 PC搭建)
人工智能·ai·c#·wpf·模型
互联网散修1 天前
鸿蒙跨设备实时绘图同步:从零到一实现分布式画板
分布式·wpf·harmonyos
晓纪同学2 天前
WPF-09 命令系统
wpf
晓纪同学2 天前
WPF-10资源系统
wpf
七夜zippoe3 天前
DolphinDB集群部署:从单机到分布式
分布式·wpf·单机·dolphindb·分集群