2009-12-20 11 views
0

J'ai des problèmes avec l'hébergement d'une application prisme WPF dans un contrôle ElementHost et je suis désespéré pour l'aide.Problèmes avec Prism hébergé dans un WinForm ElementHost

L'application PRISM fonctionne très bien dans Silverlight et dans un WPF autonome.

Le shell principal semble bien configuré dans l'élément elementHost sur un formulaire WinForm, mais les autres vues ne sont chargées que par la procédure "RegisterViewWithRegion" et non par la procédure "Add, Activate". J'ai besoin de "Ajouter, Activer" pour la portée. Cependant je crois que le problème est que je charge mon shell deux fois ... pas exprès. Je n'arrive pas à trouver un moyen d'appeler le bootsrapper et de définir l'elementHot sans appeler "Resolve" deux fois.

Voici le code pour mon WinForm et mon bootstrapper. Encore une fois tout fonctionne en utilisant "RegisterViewWithRegion".

Voici le 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; 
    } 

Voici le programme d'amorçage:

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

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

    } 
} 
+0

Je voulais aussi mentionner qu'il n'est pas nécessaire d'initialiser les modules vous-même. Vous devez remplacer le GetModuleCatalog, plutôt que d'initialiser les modules vous-même. Vous assumerez ainsi un peu moins la responsabilité de l'UnityBootsrapper. La plupart des gens remplacent InitializeModules juste pour mettre dans une petite logique qui doit se déclencher avant que les modules doivent initialiser et ils appellent base.InitializeModules() après qu'ils soient terminés. –

+0

Vous pouvez voir ici le code actuel pour les InitializeModules dans le bootstrapper de base fait des choses intéressantes que vous êtes en train de surcharger: http://msdn.microsoft.com/en-us/library/dd490820.aspx La section juste en dessous de la le code de la méthode InitializeModules montre comment retourner un catalogue de modules :) –

Répondre

0

Le Bootstrapper règle automatiquement Application.Current.MainForm à tout ce que vous êtes revenu dans la méthode CreateShell. J'espère que vous mettez en place une application (je pense que c'est ce que vous faites dans le premier bloc If). Si oui, vous pouvez simplement changer ceci:

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

à ceci:

var shellElement = Application.Current.MainForm; 

Cela devrait fonctionner, mais il y a certainement quelques bizarreries avec le ElementHost. Nous nous sommes retrouvés avec beaucoup de bugs de rendu étranges, surtout dans un environnement Citrix. Je ne sais pas si c'est une limitation de votre configuration, mais j'ai pensé que je le mentionnerais.

Bonne chance!

0

J'ai eu le même GCE (Gross Conceptual Error). Je voyais le même comportement de mes vues étant instancié deux fois en utilisant Ajouter ou Activer. J'étais profondément dans déboguer les comportements quand il m'a frappé.

Retourne une nouvelle instance de ShellContainer.

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

Soit enregistrer votre type de ShellContainer dans le récipient avec un ContainerControlledLifetimeManager ou mettre une propriété prublic sur votre bootstrapper pour accéder à l'instance ShellContainer à mettre dans votre ElementHost.