目录
Prism中的基本对象
数据与行为对象
1. BindableBase:数据绑定的基础
作用与特性
关键方法
使用示例
2. DelegateCommand/DelegateCommand :行为的封装
作用与特性
关键方法
使用示例
无参数命令
带参数的命令
在 XAML 中绑定命令
Prism框架中的IoC(控制反转)容器
1. 核心接口与配置
1.1 容器配置入口
1.2 关键接口
2. 服务注册方式
2.1 基础注册
2.2 生命周期控制
3. 依赖注入方式
3.1 构造函数注入(推荐)
3.2 属性注入(需谨慎)
4. 模块化中的IoC
5. 解析服务
6. 高级功能
6.1 命名注册
6.2 延迟加载与工厂模式
Prism框架中的消息对象(事件总线)
1. 核心组件
2. 使用流程
2.1 定义事件类
2.2 发布事件
2.3 订阅事件
3. 高级配置
3.1 订阅选项
各参数的应用场景总结
详细使用教程
1. 主要委托方法(回调逻辑)
2. 消息过滤条件(filter)
3. 消息委托的引用方式(keepSubscriberReferenceAlive)
4. 多线程状态控制(ThreadOption)
3.2 取消订阅
4. 实际应用场景
4.1 跨模块通信
4.2 全局状态通知
4.3 弹窗交互
Prism框架中的弹窗对象
1. 核心组件
1.1 IDialogService
1.2 IDialogAware
2. 创建弹窗的完整流程
2.1 定义弹窗视图(View)
2.2 实现弹窗ViewModel
2.3 注册弹窗
3. 触发弹窗显示
3.1 在ViewModel中调用弹窗
3.2 直接通过View触发(不推荐,破坏MVVM)
4. 高级功能
4.1 自定义弹窗样式
4.2 异步弹窗交互
4.3 弹窗传参与复杂数据
Prism框架中的区域化管理(Region Management)
1. 核心概念
2. 区域的定义与注册
2.1 在XAML中标记区域
2.2 通过代码动态注册区域
3. 视图注入与导航
3.1 向区域注入视图
3.2 视图导航生命周期
4. 区域适配器(支持复杂控件)
5. 区域上下文(共享数据)
Prism框架中的模块化设计
1. 模块的核心组成
2. 模块的创建与配置
2.1 定义模块
2.2 模块目录配置
3. 模块加载策略
4. 模块间的通信与解耦
BindableBase
是 Prism 中实现 数据绑定通知 的核心基类,继承自 INotifyPropertyChanged
接口。它简化了属性变更通知的触发逻辑,确保 UI 能够自动响应数据变化。
SetProperty
方法设置属性值,自动触发 PropertyChanged
事件。if (value != field) { ... }
和事件触发逻辑。BindableBase
,直接使用其功能。SetProperty(ref T field, T value)
:基础属性设置。SetProperty(ref T field, T value, Action onChanged)
:设置属性并执行回调。RaisePropertyChanged(string propertyName)
:手动触发指定属性的通知。public class UserViewModel : BindableBase
{
private string _name;
public string Name
{
get => _name;
set => SetProperty(ref _name, value); // 自动触发PropertyChanged事件
}
private int _age;
public int Age
{
get => _age;
set => SetProperty(ref _age, value, () =>
{
// 可选:属性变更后的回调逻辑(如验证)
});
}
}
DelegateCommand
是 Prism 对 ICommand
接口的实现,用于将 UI 操作(如按钮点击) 绑定到 ViewModel 中的方法,支持条件执行(CanExecute
)。
CanExecute
控制命令是否可用(如按钮禁用状态)。DelegateCommand
无参数,DelegateCommand
支持参数传递。Execute()
:命令执行时调用的方法。CanExecute()
:返回 bool
,决定命令是否可用。RaiseCanExecuteChanged()
:手动触发 CanExecute
的重新检查。public class UserViewModel : BindableBase
{
// 定义命令
public DelegateCommand SaveCommand { get; }
public UserViewModel()
{
// 绑定执行方法与条件检查
SaveCommand = new DelegateCommand(ExecuteSave, CanSave);
}
private void ExecuteSave()
{
// 保存逻辑
}
private bool CanSave()
{
// 检查保存条件(如数据有效性)
return !string.IsNullOrEmpty(Name);
}
// 当Name属性变化时,手动触发CanExecute检查
public string Name
{
get => _name;
set
{
SetProperty(ref _name, value);
SaveCommand.RaiseCanExecuteChanged(); // 通知命令重新检查条件
}
}
}
public DelegateCommand DeleteCommand { get; }
public UserViewModel()
{
DeleteCommand = new DelegateCommand(ExecuteDelete, CanDelete);
}
private void ExecuteDelete(int userId)
{
// 删除指定用户
}
private bool CanDelete(int userId)
{
return userId > 0; // 仅当userId有效时允许执行
}
在Prism框架中,IoC容器是实现依赖注入(DI)的核心机制,用于管理组件生命周期、解耦服务依赖并支持模块化开发。Prism默认支持多种容器(如 Unity、DryIoc)。
Prism应用的入口类(继承自PrismApplication
)负责初始化容器:
public partial class App : PrismApplication
{
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// 注册全局服务
containerRegistry.RegisterSingleton();
containerRegistry.Register();
}
protected override Window CreateShell()
{
return Container.Resolve();
}
}
IContainerRegistry
:用于注册服务(接口与实现的映射)。IContainerProvider
:用于解析(获取)已注册的服务实例。接口绑定实现类:
containerRegistry.Register();
直接注册具体类(无需接口):
containerRegistry.Register();
单例(Singleton):全局唯一实例。
containerRegistry.RegisterSingleton();
瞬态(Transient):每次解析创建新实例。
containerRegistry.Register();
实例注册:直接注入已有实例。
var logger = new FileLogger();
containerRegistry.RegisterInstance(logger);
ViewModel或服务通过构造函数声明依赖,容器自动注入:
public class UserViewModel
{
private readonly IDataService _dataService;
public UserViewModel(IDataService dataService)
{
_dataService = dataService; // 由容器自动注入
}
}
通过 [Dependency]
特性标记需注入的属性:
public class OrderService
{
[Dependency]
public ILogger Logger { get; set; }
}
每个Prism模块(实现 IModule
接口)可独立注册服务:
public class DataModule : IModule
{
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register();
}
public void OnInitialized(IContainerProvider containerProvider)
{
// 模块初始化逻辑(如预加载数据)
}
}
通过 IContainerProvider
或构造函数隐式解析服务:
// 在ViewModel中解析服务
public class MainViewModel
{
public MainViewModel(IContainerProvider containerProvider)
{
var service = containerProvider.Resolve();
}
}
同一接口多个实现时,使用名称区分:
containerRegistry.Register("Email");
containerRegistry.Register("SMS");
// 解析指定名称的实现
var emailService = container.Resolve("Email");
通过 Func
或 IocContainer.CreateScope
实现复杂依赖管理:
containerRegistry.Register(() => new ServiceFactory());
在Prism框架中,事件总线(Event Aggregator) 是实现松耦合跨组件通信的核心机制。它通过发布-订阅模式(Pub-Sub)让不同模块、视图或服务之间无需直接引用即可传递消息,尤其适用于模块化架构和MVVM模式。
IEventAggregator
:public class MyViewModel
{
private readonly IEventAggregator _eventAggregator;
public MyViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
}
}
PubSubEvent
:T
定义事件传递的数据类型。public class UserLoggedInEvent : PubSubEvent { }
创建继承自 PubSubEvent
的事件类,定义事件的数据类型:
// 无参数事件
public class AppShutdownEvent : PubSubEvent { }
// 带参数事件
public class OrderSubmittedEvent : PubSubEvent { }
通过 GetEvent
获取事件实例并发布数据:
// 发布无参数事件
_eventAggregator.GetEvent().Publish();
// 发布带参数事件
var order = new Order { Id = 123, Amount = 100.0 };
_eventAggregator.GetEvent().Publish(order);
// 订阅事件(自动强引用,需手动取消订阅)
_eventAggregator.GetEvent()
.Subscribe(OnOrderSubmitted);
// 处理事件的回调方法
private void OnOrderSubmitted(Order order)
{
// 处理订单提交逻辑
MessageBox.Show($"订单 {order.Id} 已提交!");
}
通过 Subscribe
方法的参数配置订阅行为:
_eventAggregator.GetEvent()
.Subscribe(
onOrderSubmitted, // 回调方法
ThreadOption.UIThread, // 在UI线程执行
keepSubscriberReferenceAlive: false, // 弱引用
filter: order => order.UserId == _currentUserId // 仅处理当前用户的订单
);
参数 |
典型场景 |
回调方法 |
执行具体的业务逻辑(如更新数据库、刷新UI)。 |
|
过滤无关事件(如只处理特定用户或状态的数据)。 |
|
控制订阅者生命周期(View/ViewModel用弱引用,服务层可强引用)。 |
|
解决跨线程问题(UI操作必须在UI线程,耗时操作在后台线程)。 |
Action
或带参数的委托实现。_eventAggregator.GetEvent()
.Subscribe(OnOrderSubmitted); // OnOrderSubmitted为回调方法
private void OnOrderSubmitted(Order order)
{
// 处理订单提交逻辑
_logger.Log($"订单 {order.Id} 已处理");
}
filter
)Predicate
(返回 bool
的表达式)。.Subscribe(OnHighValueOrder,
filter: order => order.Amount > 1000 // 仅处理金额超过1000的订单
);
keepSubscriberReferenceAlive
)true
:强引用,订阅者不会被垃圾回收,需手动取消订阅。false
(默认):弱引用,订阅者销毁后自动取消订阅。// 使用弱引用(推荐)
.Subscribe(OnOrderSubmitted,
keepSubscriberReferenceAlive: false
);
// 使用强引用(需手动管理)
.Subscribe(OnOrderSubmitted,
keepSubscriberReferenceAlive: true
);
Unsubscribe
。ThreadOption
)PublisherThread
:在发布事件的线程执行(默认)。UIThread
:在UI线程执行(安全更新界面)。BackgroundThread
:在线程池后台线程执行(避免阻塞UI)。// 在UI线程更新界面
.Subscribe(UpdateUI,
ThreadOption.UIThread
);
// 在后台线程处理耗时操作
.Subscribe(ProcessData,
ThreadOption.BackgroundThread
);
UIThread
,否则会抛出跨线程异常。BackgroundThread
避免阻塞主线程。PublisherThread
等同于 UIThread
。SubscriptionToken
),调用 Unsubscribe
方法。private SubscriptionToken _token;
_token = _eventAggregator.GetEvent()
.Subscribe(OnOrderSubmitted);
// 取消订阅
_eventAggregator.GetEvent().Unsubscribe(_token);
keepSubscriberReferenceAlive: false
),订阅者销毁时自动取消订阅。// 订单模块发布事件
_eventAggregator.GetEvent().Publish(order);
// 购物车模块订阅事件
_eventAggregator.GetEvent()
.Subscribe(_ => ClearCart());
// 登录成功后发布事件
_eventAggregator.GetEvent().Publish(userInfo);
// 各模块订阅事件
_eventAggregator.GetEvent()
.Subscribe(UpdateUI);
// 定义弹窗事件
public class ShowDialogEvent : PubSubEvent { }
// 发布弹窗请求
var parameters = new DialogParameters { { "message", "保存成功!" } };
_eventAggregator.GetEvent().Publish(parameters);
// 弹窗服务订阅事件并显示弹窗
_eventAggregator.GetEvent()
.Subscribe(ShowDialog, ThreadOption.UIThread);
private void ShowDialog(DialogParameters parameters)
{
_dialogService.ShowDialog("MessageDialog", parameters);
}
IDialogService
// 显示弹窗
void ShowDialog(string name, IDialogParameters parameters, Action callback);
// 显示模态弹窗(阻塞式)
void Show(string name, IDialogParameters parameters, Action callback);
IDialogAware
bool CanCloseDialog(); // 控制弹窗是否允许关闭
void OnDialogOpened(IDialogParameters parameters); // 弹窗打开时接收参数
string Title { get; } // 弹窗标题
WarningDialog.xaml
):
IDialogAware
并处理逻辑:public class WarningDialogViewModel : BindableBase, IDialogAware
{
// 实现IDialogAware
public string Title => "警告";// 弹出窗口的标题
public event Action RequestClose;// 执行关闭返回
private string _message;
public string Message
{
get => _message;
set => SetProperty(ref _message, value);
}
// 命令定义
public DelegateCommand ConfirmCommand { get; }
public DelegateCommand CancelCommand { get; }
public WarningDialogViewModel()
{
ConfirmCommand = new DelegateCommand(() =>RequestClose?.Invoke(new DialogResult(ButtonResult.OK)));
CancelCommand = new DelegateCommand(() =>RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel)));
}
// 当弹出窗口关闭时执行的逻辑
public void OnDialogClosed()
{
}
// 当弹出窗口打开的时候执行的逻辑
public void OnDialogOpened(IDialogParameters parameters)
{
// 接收参数
Message = parameters.GetValue("message");
}
public bool CanCloseDialog() => true; // 允许直接关闭
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialog("WarningDialog");
}
public class MainViewModel
{
private readonly IDialogService _dialogService;
public MainViewModel(IDialogService dialogService)
{
_dialogService = dialogService;
}
public DelegateCommand ShowDialogCommand => new DelegateCommand(() =>
{
var parameters = new DialogParameters
{
{ "message", "确定要删除此文件吗?" }
};
_dialogService.ShowDialog("WarningDialog", parameters, result =>
{
if (result.Result == ButtonResult.OK)
{
// 用户点击确认后的逻辑
DeleteFile();
}
});
});
}
App.xaml
中定义全局弹窗样式:
Task
封装弹窗结果:public async Task ShowConfirmationAsync(string message)
{
var tcs = new TaskCompletionSource();
var parameters = new DialogParameters { { "message", message } };
_dialogService.ShowDialog("ConfirmationDialog", parameters, result =>
{
tcs.SetResult(result.Result == ButtonResult.OK);
});
return await tcs.Task;
}
var order = new Order { Id = 123, Amount = 100.0 };
parameters.Add("order", order);
public void OnDialogOpened(IDialogParameters parameters)
{
var order = parameters.GetValue("order");
// 使用order数据...
}
Prism的 区域化管理(Region Management) 是其核心功能之一,用于实现动态UI组合和模块化布局。通过将界面划分为逻辑区域(Regions),各模块可独立向这些区域注入视图,无需直接操作主窗口控件,从而实现高度解耦和灵活扩展。
ContentControl
、TabControl
),用于动态承载视图。IRegionManager
):负责管理区域的生命周期、视图注入和导航。RegionAdapter
):将不同控件(如ItemsControl
、TabControl
)适配为可管理的区域。使用 prism:RegionManager.RegionName
附加属性定义区域:
在ViewModel或模块中动态创建区域:
var regionManager = Container.Resolve();
regionManager.Regions.Add("DynamicRegion", new Region());
public class OrdersModule : IModule
{
public void OnInitialized(IContainerProvider containerProvider)
{
var regionManager = containerProvider.Resolve();
regionManager.RegisterViewWithRegion("MainRegion", typeof(OrderListView));
}
}
var parameters = new NavigationParameters();
parameters.Add("orderId", 123);
_regionManager.RequestNavigate("MainRegion", "OrderDetailView", parameters);
在ViewModel中实现 INavigationAware
接口处理导航事件:
public class OrderDetailViewModel : INavigationAware
{
public void OnNavigatedTo(NavigationContext navigationContext)
{
// 获取参数
var orderId = navigationContext.Parameters.GetValue("orderId");
LoadOrder(orderId);
}
public bool IsNavigationTarget(NavigationContext navigationContext) => true;
public void OnNavigatedFrom(NavigationContext navigationContext)
{
// 清理资源
}
}
Prism内置了多种区域适配器,扩展支持常见控件:
ContentControlRegionAdapter
:适配 ContentControl
(单视图替换)。ItemsControlRegionAdapter
:适配 ItemsControl
(多视图叠加)。SelectorRegionAdapter
:适配 TabControl
、ListBox
等(支持选中项切换)。自定义区域适配器
若需支持特殊控件(如第三方图表容器),可继承 RegionAdapterBase
:
public class ChartRegionAdapter : RegionAdapterBase
{
protected override void Adapt(IRegion region, ChartControl regionTarget)
{
region.Views.CollectionChanged += (sender, args) =>
{
foreach (var view in region.Views)
{
regionTarget.AddSeries(view as ChartSeries);
}
};
}
}
// 注册适配器
protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
{
var mappings = base.ConfigureRegionAdapterMappings();
mappings.RegisterMapping(typeof(ChartControl), Container.Resolve());
return mappings;
}
_regionManager.Regions["MainRegion"].Context = new SharedData { UserId = 456 };
IRegionMemberLifetime
或依赖注入获取:public class OrderListView
{
public OrderListView(IRegionManager regionManager)
{
var context = regionManager.Regions["MainRegion"].Context;
}
}
每个模块需实现 IModule
接口,包含两个关键方法:
public interface IModule
{
void RegisterTypes(IContainerRegistry containerRegistry); // 注册依赖
void OnInitialized(IContainerProvider containerProvider); // 模块初始化逻辑
}
public class OrdersModule : IModule
{
// 注册模块专属服务
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register();
containerRegistry.RegisterForNavigation("OrderList"); // 注册视图
}
// 初始化模块(如预加载数据、订阅全局事件)
public void OnInitialized(IContainerProvider containerProvider)
{
var regionManager = containerProvider.Resolve();
regionManager.RegisterViewWithRegion("MainRegion", typeof(OrderListView));
}
}
通过 ModuleCatalog
定义模块的加载顺序和依赖关系,支持多种配置方式:
protected override void ConfigureModuleCatalog(IModuleCatalog catalog)
{
catalog.AddModule()
.AddModule(dependsOn: nameof(OrdersModule)) // 依赖OrdersModule
.AddModule(InitializationMode.OnDemand); // 按需加载
}
protected override IModuleCatalog CreateModuleCatalog()
{
return new ConfigurationModuleCatalog(new Uri("pack://application:,,,/modules.xml"));
}
protected override IModuleCatalog CreateModuleCatalog()
{
return new DirectoryModuleCatalog { ModulePath = @".\Modules" };
}
var moduleManager = containerProvider.Resolve();
moduleManager.LoadModule("ReportsModule");
dependsOn
确保依赖模块优先初始化。if (user.IsAdmin)
moduleManager.LoadModule("AdminToolsModule");
// 模块A注册服务
public void RegisterTypes(IContainerRegistry registry)
{
registry.Register();
}
// 模块B使用服务
public class ReportViewModel
{
public ReportViewModel(IDataExporter exporter) { ... }
}
// 模块A发布事件
_eventAggregator.GetEvent().Publish(data);
// 模块B订阅事件
_eventAggregator.GetEvent().Subscribe(RefreshData);