创建Prism项目时可以先创建WPF,然后修改App.xaml内容。也可以使用项目模板,需要在拓展中安装"Prism Tempalte Pack",然后创建新项目时,选择Prism Full App(WPF)项目即可:
下面一个WPF修改成Prism项目为例,简单使用Prism项目:
修改为:
namespace PrismDemo
{
///
/// App.xaml 的交互逻辑
///
public partial class App : PrismApplication
{
// 关系:PrismApplication 继承于 PrismApplicationBase 继承于 Application
// 快捷键:查看对象源码:fn+f12,快速实现接口,方法,抽象类:alt+enter+enter
// 快速创建构造函数:ctor
// Window窗体, StartupUri可以启动一个窗体
// CreateShell()主要负责启动一个主页面。Main
protected override Window CreateShell()
{
// 启动一个窗体MainWindow
return Container.Resolve();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
}
}
}
点击更改Name按钮后,会与mvvm框架实现效果一样,修改文本框名字,实现视图和后台修改时数据交互。
namespace PrismDemo.Views
{
///
/// Main.xaml 的交互逻辑
///
public partial class MainWindow : Window
{
MainWindowViewModel viewModel = new MainWindowViewModel();
public Main()
{
InitializeComponent();
// 把ViewModel和当前窗体MainWindow建立联系
// 只能保证:ViewModel提供的数据源可以在xaml视图上使用。
DataContext = viewModel;
}
}
}
Prism.Mvvm中的BindableBase 相当于CommunityToolkit.Mvvm中的ObservableObject
Prism.Mvvm.BindableBase中的RaisePropertyChanged()相当于CommunityToolkit.Mvvm中的ObservableObject.OnPropertyChanged() 。和视图数据交互的还可以使用SetProperty(ref _title, value);实现
Prism.Commands.DelegateCommand ===> CommunityToolkit.Mvvm中的RelayCommand
namespace PrismDemo.ViewModels
{
public class MainWindowViewModel : BindableBase
{
// DelegateCommand
public DelegateCommand ChangeNameCommand { get; private set; }
public MainWindowViewModel()
{
Name = "张三";
ChangeNameCommand = new DelegateCommand(ChangeName);
}
private void ChangeName(string obj)
{
Name = obj;
}
private string name;
public string Name
{
// 通过BindableBase.RaisePropertyChanged()可以保证xaml视图上数据变化,通知ViewModel, 重新渲染到视图。
get { return name; }
//set { name = value; RaisePropertyChanged(); }
set { SetProperty(ref name, value); }
}
}
}
如下图目录结构:
参考上面第3部分,创建WPF项目,将项目改成Prism项目,需要修改如下:
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation();
containerRegistry.RegisterForNavigation();
}
需要引入prism的命名依赖:xmlns:prism="http://prismlibrary.com/",以供控件使用。 ContentControl 只能展示用户控件窗体
namespace ModelDemo.ViewModels
{
public class MainViewModel:BindableBase
{
private readonly IRegionManager regionManager;
public DelegateCommand ChangeCommand { set; get; }
//构造函数里注入IRegionManager类,调用对象才能使用区域块跳转窗体
public MainViewModel(IRegionManager region)
{
ChangeCommand = new DelegateCommand((param) =>
{
regionManager.Regions["RegionName"].RequestNavigate(param);
});
this.regionManager = region;
}
}
}
模块化的意思就是,将上面4中的PageA和PageB页面拆分出去,单独封装为类库模块,在主程序中调用这两个模块,实现导航栏页面展示。
模块类库创建步骤:
- WPF类库项目(也可以用WPF(.Net Framework)应用程序---点击项目属性---改成类库项目)
- 每个模块都要安装程序包Prism.DryIoc
- 按约定编写每个模块库的Views(视图使用用户控件才能在主程序的
中使用本模块的视图)和ViewModels(没有视图操作可以不写) - 每个模块库都要创建配置文件XXXProfile配置文件,实现IMoudle接口,并在实现的RegisterTypes()方法中注册该页面。
- 注意: containerRegistry.RegisterForNavigation
(); 没有对视图操作的可以不用写PageAViewModel参数。例如下面MoudelA的MoudelAProfile配置文件: namespace ModuleA { public class ModuleAProfile : IModule { public void OnInitialized(IContainerProvider containerProvider) { } public void RegisterTypes(IContainerRegistry containerRegistry) { // 注册用户控件,让这个模块的用户控件视图将来在主程序中可以实现导航跳转 // RegisterForNavigation<视图,视图模型> containerRegistry.RegisterForNavigation
(); } } }
主程序添加模块步骤:
1.创建WPF(.Net Framework)应用程序项目,将这个项目改成Prism项目。
2.按照约定创建Views和ViewModels文件夹存放视图和视图模型。
3.App.xaml.cs中通过重写ConfigureModuleCatalog()方法,将创建的模块库添加进主程序:
namespace ModuleMain { ///
/// App.xaml 的交互逻辑 /// public partial class App : PrismApplication { protected override Window CreateShell() { return Container.Resolve(); } protected override void RegisterTypes(IContainerRegistry containerRegistry) { } //=== 方式1: ConfigureModuleCatalog配合Profile(IModule) // 需要在主项目中把依赖的两个模块库ModuleA和ModuleB的dll依赖引入 // ConfigureModuleCatalog()主要负责把依赖的两个模块添加到Prism框架中进行管理. protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog) { moduleCatalog.AddModule (); moduleCatalog.AddModule (); base.ConfigureModuleCatalog(moduleCatalog); } //===方式2: ModuleMain项目完全不依赖ModuleA和ModuleB,完全解耦。 //在当前项目的bin/debug目录下新建一个Modules文件夹将模块ModuleA、ModuleB的dll复制到此文件夹下,然后下面代码里设置查找改文件夹即可 //protected override IModuleCatalog CreateModuleCatalog() //{ // return new DirectoryModuleCatalog() { ModulePath = @".\Modules" }; //} //===方式3:通过配置文件app.config实现模块化,提醒:需要把ModuleA.dll和ModuleB.dll放到主项目的bin/debug文件夹中 //protected override IModuleCatalog CreateModuleCatalog() //{ // return new ConfigurationModuleCatalog(); //} } } 4.主视图中引用命名依赖:xmlns:prism="http://prismlibrary.com/"。定义区域块:
prism:RegionManager.RegionName="ContentRegion"/>,用来实现用户控件跳转展示
5.MainViewModel主程序中视图模型中:
如果需要后台和视图数据交互时,视图模型就需要继承BindableBasea类,在字段的set里就可以编写:RaisePropertyChanged()实现交互。
namespace MoudelMain.ViewModels { public class MainViewModel { public DelegateCommand
OpenPage { get; set; } private readonly IRegionManager regionManager; //构造函数中注入IRegionManager类实现区域管理。 //Regions["ContentRegion"]找到视图中定义的区域。 //RequestNavigate("PageA")实现页面导航跳转展示 public MainViewModel(IRegionManager regionManager) { OpenPage = new DelegateCommand (Open); this.regionManager = regionManager; } private void Open(string obj) { regionManager.Regions["ContentRegion"].RequestNavigate(obj); } } } 效果展示: