如何在我的Prism应用程序(如MS Office)中使用多个外壳? [英] How to do multiple shells in my Prism app (like MS Office)?

查看:109
本文介绍了如何在我的Prism应用程序(如MS Office)中使用多个外壳?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试创建一个具有Windows行为的应用程序,例如MS Office,例如Word/Excel.用户打开应用程序,然后单击新建",将出现一个带有应用程序外观的全新窗口.

I try to create an application that has a window behaviour as MS Office, for example Word/Excel. The user opens the application and when clicking new, a completely new window shall appear with the look of the application.

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

The closest that I found so far is this: Link

但是,这里的shell在应用程序启动时显示.如何通过命令执行此操作,或者可能有完全不同的方法来实现此目的?

However, here the shells are shown at application start. How to do this by command, or maybe there is a completely different way to achieve this?

我现在也发现了以下内容:链接,但是在哪里以及如何调用此代码?

I have also found the following now: Link, but where and how to call this code?

推荐答案

创建多个shell是正确的想法.您只需要适当地注意细节即可.

Creating multiple shells is the correct idea. You just need to take care of the details appropriately.

棱镜方式当然是让DelegateCommand处理新外壳的创建.考虑到该命令并不严格属于任何特定的ViewModel(我想说它具有应用程序范围的范围),所以对我来说,最好使用具有CreateNewShellCommand静态属性的public static class ApplicationWideCommands.然后,您可以使用{x:Static}从XAML绑定到它,也可以根据需要从代码隐藏中执行它.

The Prism way is, of course, to have a DelegateCommand handle the creation of a new shell. Considering that this command does not strictly belong to any particular ViewModel (I 'd say it has an application-wide scope), it feels better to me to have a public static class ApplicationWideCommands with a CreateNewShellCommand static property. You can then either bind to it from XAML with {x:Static} or execute it from code-behind as needed.

此命令需要注意两件事:

This command would need to take care of two things:

  1. 创建新的Window(实际上是Shell)
  2. 为新外壳实例化一个新的IRegionManager,以使现有外壳中的区域与新外壳中的区域之间的区域名称没有冲突
  3. 指示新外壳中属于新IRegionManager
  4. 的区域
  1. Create the new Window (actually, a Shell)
  2. Instantiate a new IRegionManager for the new shell, so that there is no conflict in region names between the regions in the existing shell and those in the new shell
  3. Instruct the regions in the new shell that they belong to the new IRegionManager

我将首先解决这个问题,因为它更容易解释.

I 'll tackle this last-to-first, because it's easier to explain.

在Prism中声明区域时,除了区域名称之外,您还可以声明要使用的区域管理器.通常您不需要这样做,但是在这里我们需要选择要使用的RegionManager,因为区域名称在单个区域管理器的范围内必须是唯一的.由于区域名称是在视图的XAML中进行硬编码的,因此给它们分配另一种方法将是一个很大的麻烦,因此我们需要更改等式的另一半:每个shell使用的区域管理器实例.因此,在Shell.xaml内部可能是这样的:

When declaring a region in Prism you can declare the region manager to use in addition to the region name. Normally you don't need to do this, but here we need to choose which RegionManager to use because region names must be unique in the scope of a single region manager. Since the region names are hardcoded inside the XAML of the Views, and it would be a major pain to assign them another way, we need to change the other half of the equation: the region manager instance used by each shell. So inside Shell.xaml there might be something like this:

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

这将指示每个外壳中的"WorkspaceRegion"属于绑定提供的IRegionManager.由于外壳通常没有DataContext,因此我们可以在外壳类本身中声明RegionManager属性:

This will instruct the "WorkspaceRegion" in each shell that it belongs to the IRegionManager provided by the binding. Since the shell usually has no DataContext, we can declare the RegionManager property in the shell class itself:

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

    public IRegionManager RegionManager { get; private set; }
}

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

So now we just need to make sure that each Shell instance gets its own RegionManager. For the "first" shell, this will be done by the BootStrapper. (The code below uses the DI container to resolve objects, and the examples use the UnityContainer. If you use MEF for dependency injection just mentally translate to the equivalent code.)

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完成:

For the other shells, it will be done by the 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).

There is an important caveat here: The RegionManager is registered into the container as a singleton. This means that whenever you resolve IRegionManager you will be getting back the same instance. For this reason, we create a new instance by calling the IRegionManager.CreateRegionManager method (this applies Prism v4; I 'm not sure about v2).

这时,您知道如何创建任意数量的新Shell实例并相应地连接区域.

At this point, you know how to create any number of new Shell instances and wire up the regions accordingly.

您需要注意的最后一个细节是,每个外壳托管的所有区域,无论其外观树有多深,都必须绑定到相同的RegionManager .

The final detail you need to take care of is that all regions hosted in each shell, no matter how deep in its visual tree, have to bind to the same RegionManager.

这意味着您必须像上面在ContentControl示例中所做的那样,将区域管理器显式设置为对应用程序中所有视图中的所有区域使用.幸运的是,这样做很容易,因为:

This means that you have to explicitly set the region manager to use like we did in the ContentControl example above for all regions in all Views in your application. Fortunately, this is done quite easily because:

  1. 所有视图最终将成为视觉树中Shell的后代
  2. Shell已经公开了正确的RegionManager作为属性,因此我们可以绑定到该属性
  1. All Views will end up being descendants of a Shell in the visual tree
  2. The Shell already exposes the correct RegionManager as a property, so we can bind to that

您将这样做:

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

所有设置!

您现在应该准备出发了.

All set!

You now should be ready to go.

这篇关于如何在我的Prism应用程序(如MS Office)中使用多个外壳?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆