wpf – 如何在我的Prism应用程序(如MS Office)中执行多个shell?

我尝试创建一个具有窗口行为的应用程序作为MS Office,例如Word / Excel.用户打开应用程序,当单击新建时,将出现一个全新的窗口,并显示应用程序的外观.

到目前为止我发现的最接近的是:Link

但是,这里的shell在应用程序启动时显示.如何通过命令来做到这一点,或者是否有完全不同的方式来实现呢?

编辑:
我现在还发现以下内容Link,但是在哪里和如何调用这个代码

创建多个shell是正确的想法.您只需要适当地处理细节.

何时以及如何创建新的Shell

当然,Prism的方式是让DelegateCommand处理创建一个新的shell.考虑到这个命令并不完全属于任何特定的viewmodel(我认为它有一个应用程序范围),对于一个具有CreateNewShellCommand静态属性的公共静态类ApplicationWideCommands,感觉更好.然后,您可以使用{x:Static}从XAML绑定,也可以根据需要从代码隐藏执行.

这个命令需要照顾两件事情:

>创建新窗口(实际上是一个Shell)
>为新的shell实例化一个新的IRegionManager,以便现有shell中的区域与新shell中的区域之间的区域名称没有冲突
>指示新shell中属于新IRegionManager的区域

我会处理这个最后一个,因为它更容易解释.

给你的新Shell一个新的RegionManager

在Prism中声明一个区域时,除了区域名称之外,您还可以声明使用区域管理器.通常,您不需要这样做,但是在这里,我们需要选择要使用哪个RegionManager,因为区域名称在单个区域管理器的范围内必须是唯一的.由于区域名称在视图的XAML内被硬编码,并且以另一种方式分配它们将是一个很大的痛苦,我们需要改变方程的另一半:每个shell使用的区域管理器实例.所以在Shell.xaml里面可能会有这样的东西:

<ContentControl
  regions:RegionManager.RegionManager="{Binding RegionManager}"
  regions:RegionManager.RegionName="ExampleRegion"
/>

这将指示它属于由绑定提供的IRegionManager的每个shell中的“WorkspaceRegion”.由于shell通常没有DataContext,所以我们可以在shell类中声明RegionManager属性

public partial class Shell : Window
{
    public Shell(IRegionManager regionManager)
    {
        this.RegionManager = regionManager;
        InitializeComponent();
    }

    public IRegionManager RegionManager { get; private set; }
}

所以现在我们只需要确保每个Shell实例都有自己的RegionManager.对于“第一”shell,这将由BootStrapper完成. (以下代码使用DI容器来解析对象,示例使用UnityContainer.如果使用MEF进行依赖注入,则只需精神上转换为等效代码.)

protected override DependencyObject CreateShell()
{
    // I am assuming you have a reference to the DI container
    var regionManager = this.Container.Resolve<IRegionManager>();
    return new Shell(regionManager);
}

对于其他shell,它将由CreateNewShellCommand完成:

private static ExecuteCreateNewShellCommand()
{
    // I am assuming you have a reference to the DI container
   var regionManager = this.Container.Resolve<IRegionManager>();
   ver newRegionManager = regionManager.CreateRegionManager();
   var shell = new Shell(newRegionManager);

   // The rest is easy,for example:
   shell.Show();
}

这里有一个重要的注意事项:RegionManager作为单例注册到容器中.这意味着每当您解决IRegionManager时,您将收到相同的实例.因此,我们通过调用IRegionManager.CreateRegionManager方法创建一个新的实例(这适用于Prism v4;我不知道v2).

此时,您将了解如何创建任意数量的新Shell实例并相应地连接该区域.

UI组成详细信息

您需要关心的最终细节是,每个shell中托管的所有区域,无论其视觉树中的深度如何,都必须绑定到同一个RegionManager.

这意味着您必须明确地将区域管理器设置为使用,就像我们在上述ContentControl示例中对应用程序中所有视图中的所有区域进行的操作一样.幸运的是,这很容易,因为:

>所有视图都将成为视觉树中Shell的后代
> Shell已经暴露了正确的RegionManager作为属性,因此我们可以绑定到该属性

你会这样做:

<ItemsControl
  regions:RegionManager.RegionManager="{Binding RegionManager,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Shell}}}"
  regions:RegionManager.RegionName="AnotherRegion"
/>

可以了,好了!

你现在应该准备好了.

相关文章

普通模式 >G 增加当前行到文档末尾处的缩紧层级 $ 移动到本行的末尾 . 相当于一个...
原文连接: https://spacevim.org/cn/layers/lang/elixir/ 模块简介 功能特性 启用模块 快捷键 语言专属...
原文连接: https://spacevim.org/cn/layers/lang/dart/ 模块简介 功能特性 依赖安装及启用模块 启用模...
 =   赋值操作符,可以用于算术和字符串赋值 +        加法计算     -        减法运算...
1.根据包名来查看指定的APP指定数据 adb shell "top | grep com.xxx.xxx" 由于这样打印出来的数...
ctrl+F 向下翻页 ctrl+B 向下翻页 u 取消最近一次操作 U 取消当前行的操作 ZZ 保存当前内容并退出 gg 跳...