【问题标题】:Open second shell in prism v4 WPF app (regions)在 prism v4 WPF 应用程序(区域)中打开第二个 shell
【发布时间】:2010-12-06 10:47:27
【问题描述】:

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

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

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 中?我想我需要作用域的 RegionManager,但我不知道如何使用它们。

2) 我有一些事件 (EventAggregator) 用于加载到区域中的视图来传达通知和命令(状态更新、视图关闭、错误)以供 Shell 报告。如何将主要的 shell 事件与弹出窗口事件分开(因为两者都是同一个 shell)?

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

【问题讨论】:

  • 我只是想知道为什么要再次打开一个shell?如果 shell 是您需要重用的视图,为什么不将细节概括出来,在其上创建两个包装器。一个是shell,另一个是可以多次打开的视图。
  • 外壳是我的包装器,包含一个带有许多项目的 TabControl。我只是希望用户能够为相同类型的视图打开第二个包装器,这样他就可以并排查看它们。
  • 无论如何,我不知道如何实现您的建议:如何为两个或多个视图中的每一个分隔区域和事件。

标签: wpf shell prism mef


【解决方案1】:

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

【讨论】:

  • Shell.cs 包含一个 MainRegion。我将一些东西加载到这个 MainRegion 中。现在我想打开第二个窗口,其中包含相同的 shell.cs,但加载到 MainRegion 中的内容不同。我没有shell1.cs和shell2.cs,只有一个shell.cs。
  • 现在是我不明白 :) 第一个外壳是标准外壳,在引导程序中创建。我可以添加代码,但它真的很像任何 prism 示例(引导程序、shell、mainregion)。
  • 抱歉,我花了一些时间。我用来源和希望更好的解释扩展了我的问题。
【解决方案2】:

您尝试实现的目标是可能的,尽管对于您的方法可能有些事情我并不完全理解。

我假设当您谈论拥有两个 Shell 时,您实际上是指同时拥有两个活动窗口。

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

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

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

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

【讨论】:

  • 好吧,也许我的方法是废话,但我不知道更好。有时我想在主 shell 中打开一个 View 作为 TabItem,有时作为弹出窗口(在 2n shell 或任何东西中。就像弹出窗口一样)。
  • 哦,我不知道如何创建新的 RegionManager 并将其附加到窗口 - 每当我尝试 XAML 中的区域时,RegionMananger 中都会丢失。
  • 可以在这篇文章中找到如何将 RM 附加到新窗口的示例:blogs.southworks.net/dschenkelman/2010/01/26/…。我并不是要暗示您的方法是废话,我实际上认为您正在尝试做的事情是有道理的。我只是想提供一种可能的方式来重用大部分代码并实现您需要的不同行为。
  • 该示例在启动时创建了两个具有不同区域的 shell 窗口,稍后我将尝试创建一个包含相同区域的弹出窗口。所以我的地区冲突仍然存在:(
猜你喜欢
  • 1970-01-01
  • 2014-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多