一个wpf项目的搭建prism框架mvvm
一个wpf项目的搭建prism框架mvvm
一 . 简单prism项目:
1.新建一个wpf的项目
2.引入包:在nuget中,prism.DryIoc
3.把空项目应用转化成Prism,把App基类Application改为PrismApplication,
因为这个基类是分布类, 其中app.xaml.cs基类改为PrismApplication,和xaml的标签,引入命名空间后改为<prism:prismApplication>
4并实现,这个类的两个抽象方法,其中,一个是启动类,另一个是注入的IOC容器管理。
/// <summary> /// Interaction logic for App.xaml /// </summary> public partial class App : PrismApplication { protected override Window CreateShell() { return Container.Resolve<MainWindow>(); } protected override void RegisterTypes(IContainerRegistry containerRegistry) { } }
<prism:PrismApplication x:Class="xiaoetong_wpf.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:xiaoetong_wpf" xmlns:prism="http://prismlibrary.com/"> <Application.Resources> </Application.Resources> </prism:PrismApplication>
另外:visual studio Templape,类库, 在nuget中搜索安装, 起作用是,可以快速建立Prism的项目(生产干净的MVVM目录)。
二。prism框架的主要功能
其也有命名约定,页面放在views中,如xxPage.xaml和mainWindow.xaml,则在ViewModels最好xxPageViewModel和MainWindowViewModel这样命名.
如果不这样命名,就需要手动关联,view初始化中:this.DataContext = new XXViewModel();
还有在App.xaml.cs中也可以设置:
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<ViewA, ViewAViewModel>();
}
a. region 区域 (弱化模块之间的关系) 类似于 vue布局中的组件,或网页中的iframe
b. moduel 模块
c. MVVM
d.Event Aggregetor 事件聚合器
e. Navigation 导航
f.Dialog (对话)
------------------ 1.region区域
region只有几个控件适配器,承载内容,比如stackpanel没有,它就不能写region属性,如果需要,就得自己写stackpanle的控件适配器,继承相应泛型类RegionAdapterBase<StackPanel>, 重写相应方法。
常用类:Region,RegionManage,RegionAdapter
1.实现一个简单的导航
再xml中加 (这样的话,页面就可以和逻辑代码关联了,前提是要遵守prism的目录命名规则)
xmlns:prism="http://prismlibrary.com/"
xmlns:viewmodels="clr-namespace:WpfApp2.ViewModels"
prism:ViewModelLocator.AutoWireViewModel="True"
2-1. 下面这种方式,需要再逻辑代码中处理OpenPage每次点击后,根据参数实例化页面,改变page值,从而实现导航
<Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <StackPanel > <Button Content="Button 1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10" Command="{Binding OpenPage}" CommandParameter="ViewA"/> <Button Content="Button 2" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10" Command="{Binding OpenPage}" CommandParameter="ViewB" /> </StackPanel> <!--ContentControl prism:RegionManager.RegionName="MainContentRegion" Grid.Row="1" Grid.Column="1" /--> <ContentControl Content="{ Binding page}" Grid.Row="1" Grid.Column="1" /> </Grid>
public class MainWindowViewModel: BindableBase { private IRegionManager _regionManager; public MainWindowViewModel(IRegionManager regionManager) { _regionManager = regionManager; OpenPage = new DelegateCommand<String>(openPage1); } private Object _page; public Object page { get { return _page; } set { _page = value; RaisePropertyChanged(); } } public DelegateCommand<String> OpenPage { get; private set; } private void openPage1(String target) { Console.WriteLine(target); switch (target) { case "ViewA": page = new WpfApp2.Views.ViewA(); break; case "ViewB": page = new WpfApp2.Views.ViewB(); break; } } }
2-2. 页面通过prism注入服务注入进去--实现导航
a.再app.xaml中
protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterForNavigation<ViewA>(); containerRegistry.RegisterForNavigation<ViewB>(); }
a-1.也可以注册到views页面的初始化方法中
b.
<Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <StackPanel > <Button Content="Button 1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10" Command="{Binding OpenPage}" CommandParameter="ViewA"/> <Button Content="Button 2" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10" Command="{Binding OpenPage}" CommandParameter="ViewB" /> </StackPanel> <ContentControl prism:RegionManager.RegionName="MainContentRegion" Grid.Row="0" Grid.Column="1" /> </Grid>
c.
public class MainWindowViewModel: BindableBase { private IRegionManager _regionManager; public MainWindowViewModel(IRegionManager regionManager) { _regionManager = regionManager; OpenPage = new DelegateCommand<String>(openPage1); } private Object _page; public Object page { get { return _page; } set { _page = value; RaisePropertyChanged(); } } public DelegateCommand<String> OpenPage { get; private set; } private void openPage1(String target) { Console.WriteLine(target); _regionManager.Regions["MainContentRegion"].RequestNavigate(target); } }
------------------2 模块
a.新建一个wpf应用程序,修改属性为类库,进入prism包,建立相应目录后,再模块根目录建立一个集成IModule接口的文件,重写方法。
ModelCProfile: (把页面注册到导航)
public class ModelCProfile : IModule { public void OnInitialized(IContainerProvider containerProvider) { } public void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterForNavigation<ViewC1>(); } }
b-1 .(代码方式)再另一项目程序,引用dll, 添加引用,选择项目。
再这个项目程序的App.xaml.cs,重写一个ConfigureModuleCatalog方法,添加引入的模块名配置文件。
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog) { moduleCatalog.AddModule<ModelCProfile>(); base.ConfigureModuleCatalog(moduleCatalog); }
然后,和上面的区域调用方式一样。
(配置方式)把模块生成dll,放在目录中,然后扫码目录,不用引用了。
再项目中新建一个文件夹,module目录,把dll复制到里面去,然后,再App.xaml.cs,重写一个CreateModuleCatalog方法。(注意新建放模块的文件要始终复制)
protected override IModuleCatalog CreateModuleCatalog() { return new DirectoryModuleCatalog() { ModulePath = @".\Modules" }; }
-------------3.导航
那个业务,为导航,就在这个业务原有继承BindableBase接口的同时,继承导航相关接口IConfirmNavigationRequest,并实现相应方法,导航上下文等,纪录浏览过程,实现前进和后退。