4

Je développe mon propre concepteur WinForms. Il doit être capable de charger des types de formulaires personnalisés existants. L'un des problèmes que je rencontre est des formulaires sans ctor par défaut: Mon code instancie actuellement le formulaire avant de pouvoir le charger dans le concepteur, ce qui nécessite un ctor par défaut.Comment le Concepteur Winforms instancie-t-il mon formulaire?

OTOH, VS2008 est capable de charger de telles formes. Je crois qu'il n'instancie pas réellement ma forme (comme noté dans this question): Même les cteurs par défaut ne sont pas exécutés. Et il n'exécute pas vraiment InitializeComponent(). Je viens d'ajouter un messagebox dans cette fonction et il ne s'affiche pas.

Il semble qu'il mime dynamiquement le type de formulaire personnalisé et n'exécute que des parties du code dans InitializeComponent qu'il pense être pertinent.

Est-ce que quelqu'un sait où je peux trouver plus d'informations sur le fonctionnement du concepteur VS.

TIA.

Note: J'ai trouvé ce related question sans réponses satisfaisantes

EDIT: Informations complémentaires: Steve m'a fait remarquer à CodeDom, ce qui est très insteresting. Mon problème est que les types que je dois charger dans mon concepteur sont déjà compilés au lieu d'être disponibles en tant que code source. Je ne trouve aucun moyen d'appliquer la désérialisation de CodeDom au code compilé.

+1

Vous pouvez trouver plus de chance dans la personnalisation des éléments de conception Windows Forms existants, plutôt que de les réinventer. Ils gèrent toutes sortes de scénarios auxquels vous ne penserez pas jusqu'à ce que vos utilisateurs se plaignent de leur manque. –

+1

John, c'est exactement mon point de vue. Où me voyez-vous réinventer quelque chose? –

Répondre

12

Trouvé ce here:

Lorsque vous ouvrez un nouveau projet d'application de Windows dans VS, vous voyez une forme vide appelé Form1 dans la conception vue. Maintenant, vous n'avez pas encore construit le projet , alors comment le concepteur peut-il créer une instance de Form1 et le montrer? Eh bien, le concepteur n'est pas vraiment instanciation Form1 du tout. Il crée une instance de la classe de base de Form1, c'est-à-dire System.Windows.Forms.Form. Avec une connaissance de base de la programmation orientée objet , vous trouverez que ce a intuitivement du sens. Lorsque vous créez Form1, vous commencez avec la classe de base , le formulaire et le personnalisez. C'est exactement ce que le designer vous aide à faire.

Maintenant, disons que vous avez ajouté un tas de contrôles au formulaire et fermé le concepteur . Lorsque vous rouvrez le concepteur , les contrôles sont toujours là . Cependant, le formulaire de la classe de base ne dispose pas de ces contrôles, donc si le concepteur n'exécute pas le constructeur de Form1, comment a-t-il montré les contrôles ? Le concepteur fait cela en désérialisant le code dans InitializeComponent. Chaque langue que le concepteur prend en charge a un CodeDomProvider qui est responsable pour fournir un analyseur qui analyse le code dans InitializeComponent et crée une représentation CodeDom de il. Le concepteur appelle ensuite un ensemble de CodeDomSerializers pour désérialiser ce en contrôles réels (ou plus généralement, composants) qu'il peut ajouter au formulaire de conception .Maintenant, j'ai glissé sur beaucoup de détails dans cette description , mais le point ici est que le constructeur de Form1 et InitializeComponent ne sont jamais vraiment . Au lieu de cela, le concepteur analyse les instructions dans InitializeComponent pour déterminer les contrôles à instancier et ajouter au formulaire.


Ce qui précède est la façon dont Windows Forms dans Visual Studio charge un formulaire. Si ce que vous cherchez est un moyen de créer une instance d'un formulaire qui n'a pas de constructeur par défaut et ont toujours accès aux composants/contrôles contenus, je ne suis pas au courant d'une solution. La seule méthode que je suis au courant vous permet de contourner l'absence d'un constructeur par défaut est FormatterServices.GetUninitializedObject, mais méfiez-vous ...

Parce que la nouvelle instance de l'objet est initialisé à zéro et aucun constructeurs sont Exécuter, l'objet peut ne pas représenter un état considéré comme comme valide par cet objet.

Moi aussi j'ai une application qui nécessite instanciation formes compilées, mais ont toujours utilisé Activator.CreateInstance et autres nécessaires aux développeurs d'inclure, à tout le moins, un constructeur par défaut privé si elles veulent que leur forme accessible dans mon application. Puisque nous possédons l'intégralité de la base de code et que tout le monde est conscient de l'exigence, ce n'est pas un problème et cela fonctionne bien pour nous.

+0

Steve, lien très intéressant. Merci! Cela confirme à peu près le mécanisme général que j'imaginais mais je ne connaissais pas CodeDom. Va plonger tout de suite ;-) –

+0

CodeDoms semblent me conduire dans une impasse en essayant de charger * compilé * types de formulaires personnalisés :-( –

+0

"aucun constructeur n'est exécuté" - sur une note connexe, cela ne s'applique pas à 'UserControl's, si je mets une boucle infinie dans un constructeur de' UserControl' et essaye de le faire glisser dans un formulaire, il verrouille visual studio. Il y a aussi quelques exceptions à ce sujet dans les commentaires sur le page de blog msdn liée. – jrh

0

En plus de la réponse de Steve, si vous ajoutez un nouveau formulaire Windows à un projet, mais le rendre abstrait, vous pouvez toujours l'ouvrir dans le concepteur. Toutefois, si vous ajoutez un autre formulaire et que celui-ci provient du premier formulaire (résumé), vous obtenez une erreur lorsque vous tentez d'ouvrir le formulaire dans le concepteur.

Questions connexes