加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-15 18:54:20 所属栏目:安全 来源:网络整理
导读:我尝试创建一个具有窗口行为的应用程序作为MS Office,例如Word / Excel.用户打开应用程序,当单击新建时,将出现一个全新的窗口,并显示应用程序的外观. 到目前为止我发现的最接近的是:Link 但是,这里的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"
/>

可以了,好了!

你现在应该准备好了.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读