Prism 框架笔记及实例

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 (命令) 提供DelegateCommandDelegateCommand<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 个条件:

  1. 视图(Window/UserControl/Page)放在Views文件夹

  2. 视图模型放在ViewModels文件夹

  3. 视图模型名称格式:视图名称+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、移动端等多平台场景。

相关推荐
·心猿意码·1 小时前
告别版本地狱:C# 中央包管理
c#
k***45991 小时前
C#数据库操作系列---SqlSugar完结篇
网络·数据库·c#
lzhdim1 小时前
C#开发的应用启动菜单应用(普通版) - 开源研究系列文章 - 个人小作品
开发语言·c#
MM_MS2 小时前
C# 线程与并发编程完全指南:从基础到高级带详细注释版(一篇读懂)
开发语言·机器学习·计算机视觉·c#·简单工厂模式·visual studio
公子小六4 小时前
推荐一种手动设置异步线程等待机制的解决方案
windows·microsoft·c#·.net
code bean5 小时前
【C++】全局函数和全局变量
开发语言·c++·c#
yi碗汤园5 小时前
C#实现对UI元素的拖拽
开发语言·ui·unity·c#
m***92385 小时前
【MySQL】C# 连接MySQL
数据库·mysql·c#
ironinfo8 小时前
C#性能优化随记
开发语言·性能优化·c#