2009-02-24 6 views
4

Nous envisageons de créer une interface utilisateur WPF qui s'étend sur plusieurs domaines d'application. L'un des domaines de l'application exécuterait l'application tandis que les AppDomains restants hébergeraient une série de contrôles et de logique utilisateur. L'idée, bien sûr, est de bac à sable ces contrôles utilisateur et la logique de l'application principale.Quels sont les problèmes liés à l'exécution de WPF sur plusieurs AppDomains sur un thread d'interface utilisateur?

Here est un exemple de le faire en utilisant CRG/System.AddIn. Quelles sont certaines des expériences que d'autres ont eu avec cela? Comment cette solution gère-t-elle les RoutedEvents/Commands qui peuvent se produire à l'intérieur d'un seul contrôle utilisateur et sont-ils correctement sérialisés sur AppDomains? Qu'en est-il des ressources de WPF? Peuvent-ils être accessibles à travers AppDomains de façon transparente?

Répondre

0

J'ai répondu à une question simulaire here et édité pour WPF aussi, vous pouvez utiliser une propriété interessante de la façon dont le moteur de compisition fonctionne pour revêtir d'une pompe répartiteur, dans l'un des contextes de rendu. C'est une option vraiment légère. De plus, je suppose que vous connaissez le enterprise library et le unity?

Il ya un WPF application block donc l'utilisation de ce modèle n'est pas trop douloureuse;) Mais ils ne disent pas, pas de douleur pas de gain?

Il y a aussi CAB (Composite UI Application Block), des liens dans l'unité. Les personnes WPF SDK ont conçu une plate-forme WPF Silverlight &. (a.k.a Prisme).

Oh droite, vous a également demandé au sujet des ressources? Je préfère charger les sources de ressources manuellement dans la classe Application. Une chose que j'ai réalisé, disons que vous avez un ResourceDictionary dans un sous-dossier et que vous chargez MergedDictionaries dans ce ResourceDictionary. Donc, si dans votre classe Application, vous chargez "my-res-dir/MergedDictionaryLoader.xaml" (par code ou xaml), TOUTES LES CHARGES FUTURES DE MERGEDDICTIONARIES SONT CHARGÉES DE "mon-res-dir". Un peu fou si vous me le demandez, je pense que le répertoire actuel du processus n'a pas changé, vous devez spécifier "mon-res-dir/foo.xaml" pour tous vos répertoires supplémentaires. Cependant ce n'est pas le cas (je ne crois pas que cela soit documenté nulle part au moins très bien et devrait être considéré comme un bug imho).

Alors rappelez-vous, WPF chargement de dictionnaire de ressources va être basée hors du répertoire à partir duquel le XAML actuelle est. Donc, vous spécifiez Source = « foo.xaml » à partir de votre « my-res-dir/MergedDictionaryLoader.xaml ". J'ai même joué avec le pack URI/syntaxe absolue, mais je n'ai jamais trouvé cela aussi beaucoup plus intuatif.

2

Ancienne question, mais néanmoins: vous devrez avoir plusieurs threads d'interface utilisateur - un par AppDomain. les créer comme ceci:

 var thread = new Thread(() => 
     { 
      var app = new Application(); 
      app.Run(); 
     }); 
     thread.Name = AppDomain.CurrentDomain.FriendlyName; 
     thread.SetApartmentState(ApartmentState.STA); 
     thread.Start(); 

Le plus grand défi est alors que vous ne pouvez pas envoyer FrameworkElements entre AppDomains (ils ne sont pas MarshalByRefObject), mais vous pouvez utiliser les méthodes FrameworkElementAdapters.ViewToContractAdapter() et ContractAdapterToView() pour travailler autour de cette limitation. Voir la page MSDN FrameworkElementAdapters pour plus de détails. Puis, une fois que vous avez cela en place, le plus gros problème à mon humble avis est que vous ne pouvez rien placer sur le FrameworkElement du domaine "distant" (le classique "problème d'espace aérien"). Voir this thread pour plus d'informations à ce sujet.

Questions connexes