ric.steen
ric.steen

Reputation: 23

Instantiating multiple instances of PRISM shell

I'm trying to set up an application which allows to open multiple instances of the same window (shell). I have a main shell (which is set up by the Bootstrapper) from which I open new instances of my second shell. This second shell contains several regions.

Now there's a problem because a given region can only appear once per application (or RegionManager), so I tried to give each shell its own RegionManager. This seems to work fine, however I'm also using Unity to inject the RegionManager into my ViewModels/Controllers, which means I always get the main shell's instance instead of the one tied to the shell the ViewModel belongs to.

Is it somehow possible make this work? Is this even the right approach for my use case?

Upvotes: 2

Views: 1119

Answers (2)

Rune Vikestad
Rune Vikestad

Reputation: 4733

You can solve this with scoped regions and a custom dialog service.

I really recommend looking into Brian Lagunas' PluralSight course on Prism Problems & Solutions: Showing Multiple Shells on the topic for some nice in-depth details, which is also where this solution was derived from.

To get you started consider the following service:

public interface IShellService
{
    void ShowShell();
}

public class ShellService : IShellService
{
    private IUnityContainer _unityContainer;
    private IRegionManager _regionManager;

    public ShellService(IUnityContainer unityContainer, IRegionManager regionManager)
    {
        _unityContainer = unityContainer;
        _regionManager = _regionManager;

    }

    public void ShowShell()
    {
        shell = _container.Resolve<Shell>();

        var scopedRegion = _regionManager.CreateRegionManager();

        RegionManager.SetRegionManager(shell, scopedRegion);

        shell.Show();
    }
}

Assuming you're using Unity, you will then need to register IShellService with the ContainerControlledLifeTimeManager, which will tell your container to hold on to the instance sent to it (essentially making it a singleton).

Container.RegisterType<IShellService, ShellService>(new ContainerControlledLifeTimeManager());

You'll then simply inject IShellService wherever you need to open a new shell, and call ShowShell() on it.

private void ExecuteShowShellCommand()
{
    _shellService.ShowShell();
}

Upvotes: 2

Brian Noyes
Brian Noyes

Reputation: 2070

There are a couple ways you can handle this. Probably the easiest is to use a Scoped RegionManager: https://msdn.microsoft.com/en-us/library/ff921162.aspx http://southworks.com/blog/2011/11/30/prism-region-navigation-and-scoped-regions/

Another is that you can register named instances of IRegionManager, one per shell window, into the container, and resolve those by name. That only really works though if the ViewModels/Services that are dependent on those named instances can only be created within one Window or another.

Another way is to create a child container per window and register a separate RegionManager instance into each child container so that an attempts to resolve instances within a window goes against the region manager for that window.

Upvotes: 2

Related Questions