4
votes

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??

2
I just want to know why opening a shell again? If shell is a view that you need to reuse, why not generalize the details out, create a two wrappers over it. One is shell and another is a view you can open many times again.decyclone
The shell is my wrapper, containing a TabControl with many items. I just want the user to be able to open a second wrapper for the same types of views so he can, for example, view them side by side.Sam
Anyway, I wouldn't know how to achieve what you suggest: how to separate regions and events for each of the two or more views.Sam

2 Answers

1
votes

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.

1
votes

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.