在prism v4 WPF应用程序(区域)中打开第二个shell

时间:2010-12-06 10:47:27

标签: wpf shell prism mef

我有一个prism应用程序,包含Shell.xaml(带有MainRegion),ShellViewModel.cs。

应用程序启动时会打开此Shell窗口。现在我想打开第二个包含完全相同的shell窗口的Popup-Window(Shell.xaml,ShellViewModel)。

Shell定义与prism StockTraderRI示例类似。 Shell.xaml包含MainRegion(非常简化的源代码):

<Window x:Class="Bsoft.Test.Shell"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:cal="http://www.codeplex.com/CompositeWPF" 
    Title="MainWindow" Height="550" Width="825">
  <Grid>
    <ContentControl cal:RegionManager.RegionName="MainRegion"/>
  </Grid>
</Window>

后面的代码只包含基本的ViewModel引用:

namespace Bsoft.Test.bmedApp
{
  [Export]
  public partial class Shell : Window
  {
    [ImportingConstructor]
    public Shell()
    {
      InitializeComponent();
    }

    [Import]
    ShellViewModel ViewModel
    {
      set
      {
        this.DataContext = value;
      }
    }
  }
}

ShellViewModel由MEF加载器自动插入:

namespace Bsoft.Test.bmedApp
{
  [Export]
  public class ShellViewModel : NotificationObject
  {
    [ImportingConstructor]
    public ShellViewModel()
    {
    }
  }
}

这确实有效。

现在我想第二次打开shell窗口作为弹出窗口。很容易将Shell和ViewModel标记为不使用以下方式共享:

[PartCreationPolicy(CreationPolicy.NonShared)]

但我的问题是:

1)我将其他视图(模型)加载到MainRegion中。如何将View(Model)加载到主Shell MainRegion或弹出窗口MainRegion中,如何告诉程序?我想我需要使用范围的RegionManagers,但我不知道如何使用它们。

2)我有一些事件(EventAggregator)用于加载到区域中的视图,以便传递Shell报告的通知和命令(状态更新,查看关闭,错误)。如何从弹出窗口事件中分离主shell事件(因为两者都是相同的shell)?

我希望能够打开几个弹出窗口,因此对我来说使用不同的区域名称是不够的,我需要更多的分离。也许有办法创建一个单独的内部棱镜/ mef / region /容器框架??

2 个答案:

答案 0 :(得分:1)

我不完全明白打开两个炮弹是什么意思? 如果您在两个不同的窗口中运行Silverlight应用程序,或者您有两个WPF应用程序实例,那么您的外壳不会发生冲突。 即使你有一个带有2个Bootstrapper实例的应用程序也没有冲突 - 你的两个shell完全独立工作。 让我知道这是否有帮助。

答案 1 :(得分:1)

你想要实现的目标是可能的,虽然可能有一些我不完全了解你的方法。

我认为当你谈论有两个炮弹时,你实际上是指同时拥有两个活动窗口。

在棱镜中有many ways来实现这一点,所以让我们继续你的怀疑。

对于(1)我能想到的最好的事情是创建一个不同的Region Manager实例,将它附加到另一个Shell(弹出窗口)。这类似于使用作用域区域(因为您将拥有单独的RegionManager),但您创建管理器并将其附加到Shell。然后在MEF中使用字符串Id注册新的RegionManager,以便将其与MainWindow RegionManager区分开来,只需将区域添加到正确的区域管理器即可。

(2)是一个不同的主题,因为您试图获得相同的代码以表现不同。也许,如果您需要这样的不同行为,对两个窗口使用相同的Shell类并不是最好的方法。如果您需要这种可区分性但仍想重用代码,我建议使用某种形式的继承,并将BaseShell中的虚方法与模板方法结合起来,为每个Shell执行不同的操作。

我希望这说明了我的观点。