在 prism v4 WPF 应用程序中打开第二个 shell(区域)
我有一个棱镜应用程序,包含 Shell.xaml(带有 MainRegion)、ShellViewModel.cs。
该 Shell 窗口在应用程序启动时打开。现在我想打开第二个弹出窗口,其中包含完全相同的 shell 窗口(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 中。如何告诉程序视图(模型)是否应该加载到主 Shell MainRegion 或弹出窗口 MainRegion 中?我想我需要范围化的 RegionManager,但我不知道如何使用它们。
2)我有一些事件(EventAggregator)用于加载到区域中的视图,以传达通知和命令(状态更新、视图关闭、错误)以供外壳程序报告。如何将主 shell 事件与弹出窗口事件分开(因为两者是相同的 shell)?
我希望能够打开多个弹出窗口,因此对两个窗口使用不同的区域名称对我来说还不够,我需要更多的分离。也许有办法创建一个单独的内部 prism/mef/region/container 框架?
I've got a prism app, containing a Shell.xaml (with a MainRegion), ShellViewModel.cs.
This Shell window is opened when the app starts. Now I want to open a second Popup-Window containing the very same shell window (Shell.xaml, ShellViewModel).
The Shell definition is like in the prism StockTraderRI example. Shell.xaml contains a MainRegion (very simplified source):
<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>
Code behind contains just the basic ViewModel reference:
namespace Bsoft.Test.bmedApp
{
[Export]
public partial class Shell : Window
{
[ImportingConstructor]
public Shell()
{
InitializeComponent();
}
[Import]
ShellViewModel ViewModel
{
set
{
this.DataContext = value;
}
}
}
}
The ShellViewModel is automatically inserted by the MEF loader:
namespace Bsoft.Test.bmedApp
{
[Export]
public class ShellViewModel : NotificationObject
{
[ImportingConstructor]
public ShellViewModel()
{
}
}
}
This does work like intended.
Now I want to open the shell window a second time as a popup window. It's easy enough to mark the Shell and ViewModel as not being shared using:
[PartCreationPolicy(CreationPolicy.NonShared)]
But my problems are:
1) I load other View(Models) into the MainRegion. How do I tell the program if the View(Model) should be loaded into the main Shell MainRegion or into the popup window MainRegion? I guess I need scoped RegionManagers, but I got no clue how to use them for this.
2) I've got some events (EventAggregator) for the Views loaded into a region to communicate notification and commands (status update, view closing, errors) for the Shell to report. How can I seperate the main shell events from the popup window events (since both are the same shell)?
I want to be able to open several of the popup windows, so using different region names for both is not enough for me, I need more separation. Maybe there is a way to create a separate internal prism/mef/region/container framework??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不完全明白打开两个外壳是什么意思?
如果您在两个不同的窗口中运行 silverlight 应用程序,或者您有 2 个 WPF 应用程序实例,那么您的 Shell 不会发生冲突。
即使您的一个应用程序有 2 个 Bootstrapper 实例,也不会发生冲突 - 您的两个 shell 完全独立工作。
让我知道这是否有帮助。
I do not completely understand what do you mean by opening two shells ?
If you run your silverlight application in two different windows or you have 2 instances of your WPF app then your Shells do not conflict.
Even if you have one application with 2 instances of Bootstrapper there is no conflict - your two shells work completely independently.
Let me know whether this help.
尽管我可能不完全理解您的方法,但您想要实现的目标是可能的。
我认为当您谈论拥有两个 Shell 时,您实际上是指同时拥有两个活动窗口。
在 Prism 中有很多方法可以实现这一点,所以让我们继续解决您的疑虑。
对于(1),我能想到的最好的事情是创建区域管理器的不同实例,并将其附加到另一个外壳(弹出外壳)。这类似于使用作用域区域(因为您将有一个单独的 RegionManager),但您创建管理器并将其附加到 Shell。然后使用字符串 Id 在 MEF 中注册新的 RegionManager,以便您可以将其与 MainWindow RegionManager 区分开来,并且只需将区域添加到正确的区域管理器即可。
(2) 是一个不同的主题,因为您试图让相同的代码表现出不同的行为。也许,如果您需要如此不同的行为,那么为两个窗口使用相同的 Shell 类并不是最好的方法。如果您需要这种可区分性,但仍想重用代码,我建议您使用某种形式的继承,并将 BaseShell 中的虚拟方法与模板方法相结合,以执行每个 Shell 不同的操作。
我希望这能说明我的观点。
What you are trying to achieve is possible, although there might be some things I don't completely understand about your approach.
I assume that when you are talking about having two Shells you actually mean having two active windows at the same time.
There are many ways to achieve this in Prism, so let's get on with your doubts.
For (1) the best thing I can think of is creating a different instance of the Region manager an attaching it to the other Shell (the popup one). This is similar to working with scoped regions (as you would have a separate RegionManager), but you create the manager and attach it to the Shell instead. Then register the new RegionManager in MEF with a string Id so you can differentiate it from the MainWindow RegionManager and simply add regions to the correct region manager.
(2) is a different subject, as you are trying to get the same code to behave differently. Perhaps, if you require such different behaviors, using the same Shell class for both windows is not the best approach. If you require this kind of differentiability but would still like to reuse code I'd recommend using some form of inheritance and combining virtual methods in a BaseShell with template methods to perform the things that are different for each Shell.
I hope this illustrates my point.