Wpf Prism初体验、RegionManager区域 和 Module模块

十年河东,十年河西,莫欺少年穷

学无止境,精益求精

1、项目引入 Prism.DryIoc 

 2、规则说明

窗体必须放在Views文件夹下而且必须以View结尾,ViewModel必须放在ViewModels文件夹下面,文件必须以ViewModel结尾。

在prism框架下,可以不为窗体设定数据上下文,但,在窗体中必须显示声明:

        xmlns:Prism="http://prismlibrary.com/"  
        Prism:ViewModelLocator.AutoWireViewModel="True"

在App.xaml的cs文件中要显示声明继承自 PrismApplication

    public partial class App : PrismApplication
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainView>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        { 
        }
    }

app.xaml 更改如下:

<Prism:PrismApplication x:Class="WpfApp3.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApp3"
             xmlns:Prism="http://prismlibrary.com/" 
                        >
    <Application.Resources>
         
    </Application.Resources>
    </Prism:PrismApplication>

注:xaml中必须显示引入 xmlns:Prism ,且修改窗体标签为:<Prism:PrismApplication>   </Prism:PrismApplication>  

 xmlns:Prism="http://prismlibrary.com/" 

3、新建Views文件夹,并创建 MainView.xaml

<Window x:Class="WpfApp3.Views.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp3"
        xmlns:Prism="http://prismlibrary.com/"  
        Prism:ViewModelLocator.AutoWireViewModel="True"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal">
            <Button Content="viewA" Margin="5" Height="35" Width="100" Command="{Binding BtnCommand}" CommandParameter="viewA"></Button>
            <Button Content="viewB" Margin="5" Height="35" Width="100" Command="{Binding BtnCommand}" CommandParameter="viewB"></Button>
            <Button Content="viewC" Margin="5" Height="35" Width="100" Command="{Binding BtnCommand}" CommandParameter="viewC"></Button>
        </StackPanel>

        <ContentControl Grid.Row="1" Content="{Binding Body}"/>
    </Grid>
</Window>
View Code

4、新建 ViewModels 文件夹,并新建viewModel如下

 public class MainViewModel : BindableBase
    {
        public DelegateCommand<string> BtnCommand { get;private set; }
       


        public MainViewModel()
        {
             BtnCommand = new DelegateCommand<string>(GoUrl);
             Body = new viewA();
        }

        private object body;
        public object Body
        {
            get { return this.body; }
            set
            {
                this.body = value;
                RaisePropertyChanged();
            }
        }

        private void GoUrl(string param)
        {
            switch (param)
            {
                case "viewA": Body = new viewA(); break;
                case "viewB": Body = new viewB(); break;
                case "viewC": Body = new viewC(); break;
                default: Body = new viewA(); break;
            }
        }
    }

说明:viewModel 继承自 BindableBase,属性双向绑定需设置: RaisePropertyChanged(); ,Command命令使用: DelegateCommand,带参数的使用  DelegateCommand<T>

5、新建 UserControls 文件夹,并创建用户控件 ViewA/ViewB/ViewC

以ViewA为例

<UserControl x:Class="WpfApp3.UserControls.viewA"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApp3.UserControls"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <TextBlock Text="I am ViewA" FontSize="18"/>
    </Grid>
</UserControl>

5、效果如下:

 6、Prism:RegionManager 初体验

上述代码中,为了填充ContentControl中的内容,我们需要定义Body属性,Prism 提供了无需新建属性的方法,如下:

6.1、将 ContentControl 改为如下:

        <ContentControl Grid.Row="1" Prism:RegionManager.RegionName="ContentRegion"/>

这里定义了一个Region,名称为 ContentRegion

6.2、在App.cs中注入导航组件,如下:

        protected override Window CreateShell()
        {
            return Container.Resolve<MainView>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<viewA>("viewA");//如果不声明名字为viewA , 默认和类名一致
            containerRegistry.RegisterForNavigation<viewB>("viewB");//如果不声明名字为viewB , 默认和类名一致
            containerRegistry.RegisterForNavigation<viewC>("viewC");//如果不声明名字为viewC , 默认和类名一致
        }

6.3、修改viewModel代码如下:

    public class MainViewModel : BindableBase
    {
        public DelegateCommand<string> BtnCommand { get;private set; }



        private readonly IRegionManager regionManager;
        public MainViewModel(IRegionManager regionManager)
        {
             BtnCommand = new DelegateCommand<string>(GoUrl);
            
            this.regionManager = regionManager;
        }

     

        private void GoUrl(string param)
        {
            //regionManager.Regions["ContentRegion"].Add(new viewB());
            regionManager.Regions["ContentRegion"].RequestNavigate(param); 
        }
    }

说明: regionManager.Regions 可以获取 所有指定了 Prism:RegionManager.RegionName 的xaml 元素区域

填充的方法可以用 Add 也可以使用  RequestNavigate ,  RequestNavigate 方法中为App.cs 注册的导航名称

7、模块化

上述案例中,viewA,viewB,viewC 等和Wpf启动项目在同一个项目中,这样不便于管理,为了更好了解耦,Prism 引入了模块化 Moudle

7.1、新建Wpf项目,并删除自动创建的文件

 7.2、修改输出类型为类库

 7.3、引入 Prism.DryIoc 

 7.4、添加viewC用户控件,并新建 wpf4Profile.cs  并继承自IModule,然后实现接口

using Prism.Ioc;
using Prism.Modularity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApp4
{
    public class wpfApp4Profile : IModule
    {
        public void OnInitialized(IContainerProvider containerProvider)
        {
           
        }

        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<viewC>("viewC");
        }
    }
}

7.5、在启动的wpfApp项目中引用新建的项目

 

 7.6、app.xaml.cs 中重写 ConfigureModuleCatalog 方法

    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : PrismApplication
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainView>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            
        }

        protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
        {
            moduleCatalog.AddModule<WpfApp1Profile>();
            moduleCatalog.AddModule<WpfApp2Profile>();
            moduleCatalog.AddModule<wpfApp4Profile>();
            base.ConfigureModuleCatalog(moduleCatalog);
        }
    }

7.7、MainView xaml 同上一致,viewModel 也是一致

<Window x:Class="WpfApp3.Views.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp3"
        xmlns:Prism="http://prismlibrary.com/"  
        Prism:ViewModelLocator.AutoWireViewModel="True"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal">
            <Button Content="viewA" Margin="5" Height="35" Width="100" Command="{Binding BtnCommand}" CommandParameter="viewA"></Button>
            <Button Content="viewB" Margin="5" Height="35" Width="100" Command="{Binding BtnCommand}" CommandParameter="viewB"></Button>
            <Button Content="viewC" Margin="5" Height="35" Width="100" Command="{Binding BtnCommand}" CommandParameter="viewC"></Button>
        </StackPanel>

        <ContentControl Grid.Row="1" Prism:RegionManager.RegionName="ContentRegion"/>
    </Grid>
</Window>
View Code

cs 如下

using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using WpfApp3.UserControls;

namespace WpfApp3.ViewModels
{
    public class MainViewModel : BindableBase
    {
        public DelegateCommand<string> BtnCommand { get;private set; }



        private readonly IRegionManager regionManager;
        public MainViewModel(IRegionManager regionManager)
        {
             BtnCommand = new DelegateCommand<string>(GoUrl);
            
            this.regionManager = regionManager;
        }

     

        private void GoUrl(string param)
        {
            //regionManager.Regions["ContentRegion"].Add(new viewB());
            regionManager.Regions["ContentRegion"].RequestNavigate(param); 
        }
    }
}
View Code

 

 

 @天才卧龙的博客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章