Problems with Prism hosted in a WinForm ElementHost

1.8k views Asked by At

I am having problems with hosting a WPF prism app in an ElementHost control and am desparate for help.

The PRISM app runs fine in silverlight and in a standalone WPF.

The main Shell seems to setup fine in the elementHost on a WinForm however other views only load with the “RegisterViewWithRegion” and not the “Add,Activate” procedure. I need “Add,Activate” for scoping. However I beleive the problem is that I am loading my shell twice … not on purpose. I cannot find a way to call the bootsrapper and set the elementHot without calling “Resolve” twice.

Here is the code for my WinForm and my bootstrapper. Again everything works when using "RegisterViewWithRegion".

Here is the Winform Constructor:

   public Form1()
    {
        InitializeComponent();

        if (System.Windows.Application.Current == null)  
        {
            new MyApp();
        }

        Bootstrapper bootStrapper = new Bootstrapper();
        bootStrapper.Run();

        var shellElement = bootStrapper.Container.Resolve<ShellContainer>();

        //Attach the WPF control to the host  
        elementHost.Child = shellElement;
    }

Here is the bootstrapper:

public class Bootstrapper : UnityBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return Container.Resolve<ShellContainer>();
    }

    protected override void InitializeModules()
    {
        IModule moduleSurvey = Container.Resolve<SurveyModule>();
        moduleSurvey.Initialize();

    }
}
2

There are 2 answers

0
Mark Lindell On

I had the same GCE (Gross Conceptual Error). I was seeing the same behavior of my views being instantiated twice when using Add or Activate. I was deep into debugging the behaviors when it hit me.

The following is returning a new instance of the ShellContainer.

var shellElement = bootStrapper.Container.Resolve<ShellContainer>();

Either register your ShellContainer type in the container with a ContainerControlledLifetimeManager or put a prublic property on your bootstrapper to access the ShellContainer instance to set into your ElementHost.

0
Anderson Imes On

The Bootstrapper automatically sets Application.Current.MainForm to whatever you returned in the CreateShell method. Hopefully you are setting up an Application (I think that's what you are doing in the first If block). If so, you can just change this:

var shellElement = bootStrapper.Container.Resolve<ShellContainer>();

To this:

var shellElement = Application.Current.MainForm;

That ought to work, but there are definitely some weirdnesses with the ElementHost. We ended up with a lot of strange rendering bugs, especially in a Citrix environment. I don't know if this is a limitation of your setup, but I thought I would mention it.

Good luck!