Prism_07_WPF MVVM_复合程序视图布局

复合程序的界面(UI)是由松耦合的组件(View)组成,Prism 提供了这种页面布局的解决方案。

下面是一个由不同模块的多个视图加载到主界面来布局的:

Prism_07_WPF MVVM_复合程序视图布局

界面布局概念

一般主界面 (Shell) 是由 Regions 组成,但不关心 Region 的具体实现是什么。能够作为 Region 的容器的有:

  • ContentControl
  • ItemControl
  • TabControl

Shell

Shell 定义了程序的整体外观,包含一个或多个 Region. 模块可以在 Region 里指定呈现的视图;Region 里可以放*UI元素,比如 背景、主菜单和工具栏。

Shell 可以定义样式和边框,还可以定义样式、模板和主题。

RegionManager

RegionManager 负责创建和维护一组 region,使用适配器将 region 和 control 进行关联。

Prism_07_WPF MVVM_复合程序视图布局

RegionManager 可以通过代码 或 XAML 创建 region。Region 可以理解为是占位符,可以存放很多内容。RegionManager 提供了 RegionContext 属性,使得 regions 之间共享数据。

Region的具体实现

Region类是实现了 IRegion 接口的类,可以动态地加载 UI 元素。

Prism_07_WPF MVVM_复合程序视图布局

RegionAdapter 负责创建 Region 并关联控件。

  • ContentControlRegionAdapter - 适配System.Windows.Controls.ContentControl
  • SelectorRegionAdapter - 适配System.Windows.Controls.Primitives.Selector 和 System.Windows.Controls.TabControl
  • ItemsControlRegionAdapter - 适配System.Windows.Controls.ItemsControl

界面布局

来自不同 Modeule 的视图,在运行时会被创建和显示到特定的位置。有两种方式来实现这个功能。

View Discovery

在 ModuleManager 中通过 RegionViewRegistry 方法建立 RegionName 和 ViewType 之间的连接。在创建 Region 的时候会自动查找 ViewTypes 中与之关联的 View,并自动实例化并加载相应的视图。通过View Discovery无法控制何时加载和显示视图

通常在以下情况下使用View Discovery:

  • 需要自动加载视图
  • 区域中只包含视图的单个实例

View Injection

在视图注入中,编写代码使用 RegionManager 获取对 Region 的引用,然后将视图添加到其中。通常,这是在模块初始化或用户操作时完成的。

这样可以控制何时加载和显示视图,还可以从区域中删除视图。但无法将视图添加到尚未创建的 Region.

通常在以下情况下使用View Injection:

  • 程序使用 Navigation API
  • 程序需要对何时创建和显示视图进行控制
  • 程序需要在一个区域中显示相同视图的多个实例, 每个实例绑定不同的数据
  • 需要控制将视图添加到区域的哪个实例

Prism Library 8 包含了对 Region 的导航,允许使用 URI 导航到具体的区域,从而简化了视图注入的过程。还可以导航到上一个视图。

复合程序布局核心场景

Shell

<!--Shell.xaml (WPF) -->
<Window x:Class="StockTraderRI.Shell">

    <!--shell background -->
    <Window.Background>
        <ImageBrush ImageSource="Resources/background.png" Stretch="UniformToFill"/>
    </Window.Background>

    <Grid>

        <!-- logo -->
        <Canvas x:Name="Logo" ...>
            <TextBlock Text="CFI" ... />
            <TextBlock Text="STOCKTRADER" .../>
        </Canvas>

        <!-- main bar -->
        <ItemsControl 
            x:Name="MainToolbar"
            prism:RegionManager.RegionName="{x:Static inf:RegionNames.MainToolBarRegion}"/>

        <!-- content -->
        <Grid>
            <Controls:AnimatedTabControl
                x:Name="PositionBuySellTab"
                prism:RegionManager.RegionName="{x:Static inf:RegionNames.MainRegion}"/>
        </Grid>

        <!-- details -->
        <Grid>
            <ContentControl
                x:Name="ActionContent"
                prism:RegionManager.RegionName="{x:Static inf:RegionNames.ActionRegion}"/>
        </Grid>

        <!-- sidebar -->
        <Grid x:Name="SideGrid">
            <Controls:ResearchControl
                prism:RegionManager.RegionName="{x:Static inf:RegionNames.ResearchRegion}" />
        </Grid>

    </Grid>
</Window>

Region

Region 充当在运行时显示的一个或多个 View 的占位符,Module 可以定义 View 并添加到 Region,而无需知道 Region 显示的方式和位置。

除了可以在 XAML 中添加 Region ,还可以使用代码添加 region:

IRegionManager regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
RegionManager.SetRegionManager(this.ActionContent, regionManager);
RegionManager.SetRegionName(this.ActionContent, "ActionRegion");

View Discovery 加载视图的流程如下图所示:

Prism_07_WPF MVVM_复合程序视图布局

Prism 库提供了一个标准的注册表,向区域注册视图:

// View discovery
this.regionManager.RegisterViewWithRegion("MainRegion", typeof(EmployeeView));
// View discovery
this.regionManager.RegisterViewWithRegion("MainRegion", () => this.container.Resolve<EmployeeView>());

View Injection 加载视图的流程如下图所示:

Prism_07_WPF MVVM_复合程序视图布局

// View injection
IRegion region = regionManager.Regions["MainRegion"];

var ordersView = container.Resolve<OrdersView>();
region.Add(ordersView, "OrdersView");
region.Activate(ordersView);

默认情况,视图按照注册和添加到区域的顺序显示。Prism 库提供了 ViewSortHint 属性,允许手动排序。

我的公众号

Prism_07_WPF MVVM_复合程序视图布局

上一篇:关于Microsoft Edge 浏览器,控制台中无法显示错误信息一解。


下一篇:刷题07