Prism 中区域、模块化、导航功能、对话服务、发布订阅的简单使用
本文演示了 Prism 框架在 WPF 编程中的几个基本功能
环境:Visual Studio 2022
内容
介绍 Prism 几个基本功能,包括区域、模块化、导航功能、对话服务、发布订阅
区域
- 可以在 XMAL 中定义某 ContentControl 为 Prism 的区域,并在App中注册模块:
// 这个区域的名字为 ContentRegion
<ContentControl prism:RegionManager.RegionName="ContentRegion" />
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<ViewC>();
}
- 在 ViewModel 的构造函数中传入区域管理器的属性参数:
private readonly IRegionManager regionManager;
public MainViewModel(IRegionManager regionManager)
{
this.regionManager = regionManager;
}
- 在绑定的方法中即可通过区域管理器设置其显示的内容:
// 按钮 绑定了Open方法 传入一个string参数
<Button Margin="10" Command="{Binding OpenCommand}" CommandParameter="ModuleA" Content="Open ModuleA" />
private void Open(string obj)
{
// 可以在调用这个控件时给其传入参数
NavigationParameters keys = new NavigationParameters();
// 使用的是键值对的方式
keys.Add("Title", "Hello ModuleA");
// callback是回调函数,在执行完更改区域后会调用,可以获取该命令执行结果
regionManager.Regions["ContentRegion"].RequestNavigate(obj, callback =>
{
if ((bool)callback.Result)
{
journal = callback.Context.NavigationService.Journal;
}
}, keys);
}
- 在区域内要这样实现:
public class ModuleAViewModel : BindableBase, IConfirmNavigationRequest
{
public ModuleAViewModel()
{
}
private string title;
public string Title
{
get { return title; }
set { title = value; RaisePropertyChanged(); }
}
// 每次重新导航的时候,该实例是否重用
public bool IsNavigationTarget(NavigationContext navigationContext)
{
return true;
}
// 当从该模块离开时
public void OnNavigatedFrom(NavigationContext navigationContext) { }
// 当进入该模块时
public void OnNavigatedTo(NavigationContext navigationContext)
{
// 获取传入的参数
navigationContext.Parameters.TryGetValue<string>("Title", out title);
}
// 确认是否相应导航请求
public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
{
bool res = false;
if (MessageBox.Show("是否跳转页面?", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
{
res = true;
}
continuationCallback(res);
}
}
模块化
- 通过强引用导入模块
// 在依赖中引用 dll 并在 App 中重写该方法
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
// 添加引用-> 添加模块
moduleCatalog.AddModule<ModuleAProfile>();
moduleCatalog.AddModule<ModuleBProfile>();
base.ConfigureModuleCatalog(moduleCatalog);
}
- 指定目录动态加载,重写该方法,返回指定的目录
protected override IModuleCatalog CreateModuleCatalog()
{
// 通过目录加载
return new DirectoryModuleCatalog() { ModulePath = @".\Modules" };
}
- 在编写模块时,必须添加XXXProfile文件,并实现IModule接口
public class ModuleAProfile : IModule
{
public void OnInitialized(IContainerProvider containerProvider)
{
}
// 注册模块
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<ModuleA, ModuleAViewModel>();
}
}
导航功能
// 声明一个日志对象
private IRegionNavigationJournal journal;
public MainViewModel(IRegionManager regionManager)
{
// 实例化
this.journal = new RegionNavigationJournal();
}
// 上一步
if (journal.CanGoBack)
{
journal.GoBack();
}
// 记录journal
if ((bool)callback.Result)
{
journal = callback.Context.NavigationService.Journal;
}
对话服务
- 在 ViewModel 的构造函数中传入对话服务的属性参数:
private readonly IDialogService dialogService;
public MainViewModel(IDialogService dialogService)
{
this.dialogService = dialogService;
}
- 在对话框组件的 ViewModel 中实现 IDialogAware 接口
public class ViewDViewModel : IDialogAware
{
public string Title { get; set; }
public event Action<IDialogResult> RequestClose;
public bool CanCloseDialog()
{
return true;
}
public void OnDialogClosed()
{
}
public void OnDialogOpened(IDialogParameters parameters)
{
}
}
- 在app中注册对话框组件
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialog<ViewD, ViewDViewModel>();
}
- 使用对话服务
private void Alert()
{
// 其重载的方法也可以传入参数和回调函数
dialogService.ShowDialog("ViewD");
}
发布订阅
- 在 ViewModel 的构造函数中传入发布订阅的属性参数:
private readonly IEventAggregator eventAggregator;
public MainViewModel(IEventAggregator eventAggregator)
{
this.eventAggregator = eventAggregator;
}
- 新建一个类,实现发布订阅的接口,表示传递什么类型的消息
// 表示传递 string 消息
public class EventMessage : PubSubEvent<string>
{
}
- 订阅消息
// Subscribe订阅 UnSubscribe 取消订阅
eventAggregator.GetEvent<EventMessage>().Subscribe(message =>
{
MessageBox.Show(message);
});
- 发布消息
eventAggregator.GetEvent<EventMessage>().Publish("Hello");
总结
主要总结了一下区域、模块化、导航功能、对话服务、发布订阅的简单使用,还需要多写多熟练。
作者:chanstic
出处:Prism 中区域、模块化、导航功能、对话服务、发布订阅的简单使用
本作品采用「CC BY-NC-SA 4.0」许可协议进行许可