xaml和cs文件的关联
在prism中,前台xaml代码和后台cs代码通过命名空间建立联系,所以软件的命名空间需要合乎规范,最好是不做修改。
IRegionManager,IEventAggregator,IApplicationCommands
- IRegionManager:
之前提到过的关于界面加载的一个管理器,用于注册显示的View视图。此方法适用于项目内静态界面的注册。
注册方式如下:
_regionManager.RegisterViewWithRegion("RegionName", typeof(ViewName));
- IEventAggregator:
事件聚合器,可以实现应用程序中松散耦合组件之间的通信。允许发布者和订阅者通过事件进行通信,并且彼此之间仍然没有直接引用。使用方法如下:- 新建事件集合类文件,声明事件,格式如下:
class EventName : PubSubEvent<参数类型> { }
- 在需要使用事件的文件中引用该文件,在主程序入口处的参数列表中添加IEventAggregator参数,再定义IEventAggregator类型的变量,初始化时传递参数,即可在程序的任意位置发布事件。发布格式如下:
_eventAggregator.GetEvent<EventName>().Publish(需要发送的消息);
- 在需要订阅的初始化函数中订阅该事件,同样需要定义IEventAggregator变量和形参,订阅格式如下:
如果存在多个订阅需要进行信息筛选时,订阅格式参考如下:_eventAggregator.GetEvent<EventName>().Subscribe(订阅事件后的响应函数);
_eventAggregator.GetEvent<EventName>().Subscribe(订阅事件后的响应函数,arg=> arg.属性 进行筛选);
- 新建事件集合类文件,声明事件,格式如下:
- IApplicationCommands
复合命令,用于父视图控件调用子视图控件的命令,当一个父视图需要调用多个子视图的同一个命令时,复合命令可以实现依次调用子命令,当子命令全部调用完毕时复合命令才算完成。使用步骤如下:-
首先新建IApplicationCommands接口文件,在接口中定义CompositeCommand并实现该接口,格式如下:
public class ApplicationCommands : IApplicationCommands { //无参构造默认子命令依次执行,若仅要求当前活动视图执行子命令,可选择带monitorCommandActivity为true的参数构造,同时需要子视图的ViewModel实现IActiveAware接口 public CompositeCommand CmdName{ get; } = new CompositeCommand(); } public interface IApplicationCommands { CompositeCommand CmdName{ get; } }
-
在父视图的ViewModel中添加IApplicationCommands类型的可绑定属性,并且构造函数中添加该类型的形参进行实例化。
-
在程序的app.xaml.cs文件中对IApplicationCommands进行注册,格式如下:
protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterSingleton<IApplicationCommands, ApplicationCommands>(); }
-
在子视图的ViewModel中添加DelegateCommand命令,并且在初始化函数中添加IApplicationCommands类型的形参,注册到父视图的复合命令中,格式如下:
子命令名= new DelegateCommand(响应事件); applicationCommands.复合命令名.RegisterCommand(子命令名);
若要实现仅活动视图执行子命令,子视图的ViewModel需要实现IActiveAware接口,方法如下:
public class TabViewModel : BindableBase, IActiveAware { private bool _isActive; public bool IsActive { get { return _isActive; } set { _isActive = value; OnIsActiveChanged(); } } public event EventHandler IsActiveChanged; public DelegateCommand UpdateCommand { get; private set; } public TabViewModel(IApplicationCommands applicationCommands) { 子命令 = new DelegateCommand(响应函数); applicationCommands.复合命令.RegisterCommand(子命令); } private void OnIsActiveChanged() { 子命令.IsActive = IsActive; //改变命令属性 IsActiveChanged?.Invoke(this, new EventArgs()); //invoke the event for al listeners } } ```
-
最后在父视图的xaml中添加复合命令绑定,格式如下:
Command="{Binding ApplicationCommands.复合命令名}"
-
Module和IModuleCatalog
prism支持应用程序的模块化开发管理,将功能块作为module独立开发,耦合度低易于维护。ModuleCatalog主要用来保存应用程序可用的modules,每个module都是用ModuleInfo来定义(包含module的名称、类型和位置)。模块化开发的基本步骤如下:
-
在解决方案中利用prism template pack新建module工程,或者新建用户控件库工程(注意平台是.NET还是framework,与主程序保持一致)后添加prism NuGet包改写成Module工程
-
模块开发完成后利用ModuleCatalog对模块进行统一管理和引用,引用方式有如下多种:
(1). 在App.xaml.cs中重写ConfigureModuleCatalog(需要添加对应模块的引用)protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog) { moduleCatalog.AddModule<ModuleA>(); moduleCatalog.AddModule<ModuleB>(); base.ConfigureModuleCatalog(moduleCatalog); }
(2). 通过读取根目录Modules文件夹查找模块(不用添加模块的引用)
protected override IModuleCatalog CreateModuleCatalog() { //在软件所在目录新建Modules文件夹,以此为加载路径 return new DirectoryModuleCatalog() { ModulePath = @".\Modules" }; }
(3). 通过配置文件来配置ModuleCatalog(不用添加模块的引用)
先在App.xaml.cs中重写CreateModuleCatalogprotected override IModuleCatalog CreateModuleCatalog() { return new ConfigurationModuleCatalog(); }
这表示ModuleCatalog将从配置文件中创建
再在App.config中添加节点,并且指定需要Load的module,设置startupLoaded参数来
告诉shell,是否在启动时就加载他。下面是App.config的内容,他加载了一个名ModuleAModule
的Module,存在ModuleA.dll。<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="modules" type="Prism.Modularity.ModulesConfigurationSection, Prism.Wpf" /> </configSections> <startup> </startup> <modules> <module assemblyFile="ModuleA.dll(dll名)" moduleType="ModuleA.ModuleAModule(命名空间), ModuleA(类名), Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" moduleName="ModuleAModule" startupLoaded="True" /> </modules> </configuration>