一个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,并实现相应方法,导航上下文等,纪录浏览过程,实现前进和后退。

 

posted @ 2024-08-01 11:40  与f  阅读(146)  评论(0编辑  收藏  举报