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

 

 

 @天才臥龍的博客

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