Prism模块化和对话服务
阅读推荐
1。文档:
官方地址:http://prismlibrary.com
官方源码:https://github.com/PrismLibrary/Prism
使用Prism框架:
https://www.jianshu.com/p/ad9a39bef609
https://www.jb51.net/article/237024.htm
区域:
https://blog.csdn.net/weixin_40867123/article/details/124918411
https://www.toutiao.com/article/7316086781261693477
https://blog.csdn.net/Fioman_GYM/article/details/137688221
模块化:
https://www.jb51.net/article/237106.htm
https://zhuanlan.zhihu.com/p/685956781
https://blog.csdn.net/jjailsa/article/details/141995573
导航深入:(导航传参,导航确认(路由守卫),导航日志)
https://www.cnblogs.com/chenwolong/p/17870507.html
https://zhuanlan.zhihu.com/p/688414422
Prism模块化
如何创建项目
先安装扩展
如何添加模块
在Prism框架中,每个模块拥有完整的视图,视图模型,模块的配置文件等。
在各模版中添加视图和视图模型
ModuleAModule配置文件
// ModuleAModule是ModuleA模块的配置文件,一般建议配置文件以Config或Profile结尾
public class ModuleAModule : IModule
{public void OnInitialized(IContainerProvider containerProvider){}public void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.RegisterSingleton<View1>();containerRegistry.RegisterSingleton<View2>();}
}
ModuleBModule配置文件
public class ModuleBModule : IModule{public void OnInitialized(IContainerProvider containerProvider){}public void RegisterTypes(IContainerRegistry containerRegistry){// ModuleB模块中的View3和View4页面,我们想让这两个页面,在主项目中的MainWindow中定义的ContentRegion区域中显示。// ModulB模块中的两个页面支持跳转。containerRegistry.RegisterForNavigation<View3, View3ViewModel>();containerRegistry.RegisterForNavigation<View4, View4ViewModel>();}}
各区域如图所示
在主项目中的注册模块
public partial class App{protected override Window CreateShell(){return Container.Resolve<MainWindow>();}protected override void RegisterTypes(IContainerRegistry containerRegistry){}/** 在主项目中使用模块A步骤:* 1。先定义ModuleA,使用prism module模板。注意:每个模块拥有独立的视图,视图模型,配置文件。* 2。把ModuleA引入主项目。即添加依赖项。* 3。把ModuleA在主项目中注册一下。*/protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog){base.ConfigureModuleCatalog(moduleCatalog);// A. 代码方式(推荐)// 在主项目中添加ModuleA和ModuleB模块,其实是把模块A或B中的视图及视图模型“扔”到IOC容器中。moduleCatalog.AddModule<ModuleAModule>();moduleCatalog.AddModule<ModuleBModule>();}//App.Config配置模块/*protected override IModuleCatalog CreateModuleCatalog(){// B。目录路径(推荐),不需要强依赖,而是去Modules文件夹中找ModuleA.dll和ModuleB.dll//string path = System.IO.Path.Combine(Environment.CurrentDirectory, "../../../Modules");//return new DirectoryModuleCatalog() { ModulePath = path };// C。配置文件(推荐),需要配合App.config来使用,且需要开发者手动把ModuleA.dll和ModuleB.dll复制到主项目的bin/debug/net8.0-windows7.0//return new ConfigurationModuleCatalog();}*/}
在MainWindowViewModel中创建区域管理器
public class MainWindowViewModel : BindableBase{//在视图模型中使用该对象来管理和控制视图与区域之间的关系。在后续的代码中,视图模型会利用这个regionManager对象来进行视图的注册和操作。private readonly IRegionManager regionManager;public MainWindowViewModel(IRegionManager regionManager){this.regionManager = regionManager;}private string _title = "Prism Application";public string Title{get { return _title; }set { SetProperty(ref _title, value); }}public DelegateCommand LoadedCommand{get{return new DelegateCommand(() =>{regionManager.RegisterViewWithRegion("HeaderRegion", "View1");regionManager.RegisterViewWithRegion("LeftMenuRegion", "View2");});}}}
在左侧区域显示View2,点击View2中的按钮打开相应的控件
public class View2ViewModel : BindableBase
{private readonly IRegionManager regionManager;public View2ViewModel(IRegionManager regionManager){this.regionManager = regionManager;}public DelegateCommand<string> OpenCommand{get {return new DelegateCommand<string>((page) => {regionManager.RequestNavigate("ContentRegion", page);});}}
}
目录路径的方式使用模块
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration><!--默认情况下 configuration节点是不支持 modules节点 先使用configSections定义一个modules--><!--configSections必须是configuration第一个节点--><configSections><section name="modules" type="Prism.Modularity.ModulesConfigurationSection, Prism.Wpf" /></configSections><startup></startup><modules><module assemblyFile="ModuleA.dll" moduleType="ModuleA.ModuleAModule, ModuleA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" moduleName="ModuleAModule" startupLoaded="True" /><module assemblyFile="ModuleB.dll" moduleType="ModuleB.ModuleBModule, ModuleB, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" moduleName="ModuleBModule" startupLoaded="True" /></modules>
</configuration>
新建Modules文件夹,将dll文件粘贴到文件夹中
protected override IModuleCatalog CreateModuleCatalog(){// B。目录路径(推荐),不需要强依赖,而是去Modules文件夹中找ModuleA.dll和ModuleB.dllstring path = System.IO.Path.Combine(Environment.CurrentDirectory, "../../../Modules");return new DirectoryModuleCatalog() { ModulePath = path };}
对话服务
App.xaml.cs
public partial class App
{protected override Window CreateShell(){return Container.Resolve<MainWindow>();}protected override void InitializeShell(Window shell){base.InitializeShell(shell);// 要把Login用户控件以对话框的形式打开。// 1。需要把打开用户控件以对话框形式注册以IOC容器中。// 2。需要使用Prism提供对话服务功能。拿到对话服务。DialogService// DialogService类实现了IDialogService接口。IDialogService dialogService = Container.Resolve<IDialogService>();dialogService.ShowDialog("Login", (r) =>{// r类型是IDialogResultif (r.Result != ButtonResult.OK){Environment.Exit(0);}else{var account = r.Parameters.GetValue<string>("account");var password = r.Parameters.GetValue<string>("password");}});}protected override void RegisterTypes(IContainerRegistry containerRegistry){// 注册对话框服务// 前提:视图对应的视图模型必须实现IDialogAware接口containerRegistry.RegisterDialog<Login, LoginViewModel>();}
}
Login命令绑定
LoginViewModel.cs
public class LoginViewModel : BindableBase, IDialogAware{#region IDialogAware// 对话框的标题public string Title => "登录";// 对话框关闭事件,可以在对话框关闭时,返回结果DialogResultpublic event Action<IDialogResult> RequestClose;// 对话框是否允许关闭public bool CanCloseDialog(){return true;}// 对话框关闭时执行的方法public void OnDialogClosed(){}// 对话框打开时执行的方法 public void OnDialogOpened(IDialogParameters parameters){Account = "Hello";Password = "22222";}#endregionprivate string account = "admin";public string Account{get { return account; }set { SetProperty(ref account, value); }}private string password = "123456";public string Password{get { return password; }set { SetProperty(ref password, value); }}public DelegateCommand LoginCommand{get{return new DelegateCommand(() =>{if (Account == "admin" && Password == "123456"){// 创建参数对象var parameters = new DialogParameters{{ "account", Account },{ "password", Password }};// 关闭对话框 *** RequestClose?.Invoke()触发事件RequestClose?.Invoke(new DialogResult(ButtonResult.OK, parameters));}else{MessageBox.Show("账号或密码错误!", "提示", MessageBoxButton.OK, MessageBoxImage.Error);}});}}public DelegateCommand CancelCommand{get{return new DelegateCommand(() =>{// 关闭对话框RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel));});}}}