Charger un formulaire sans le montrer

Version courte: je veux déclencher l’événement Form_Load () sans rendre le formulaire visible. Cela ne fonctionne pas car Show () ignore la valeur actuelle de la propriété Visible:

tasksForm.Visible = false; tasksForm.Show(); 

Version longue: j’ai une application WinForms avec deux formulaires: main et tâches. Le formulaire principal est toujours affiché. L’utilisateur peut soit cliquer sur un bouton pour ouvrir le formulaire de tâches, soit cliquer sur des boutons qui exécutent directement une tâche sans ouvrir le formulaire de tâches.

Lorsqu’un utilisateur demande d’exécuter directement une tâche, j’aimerais simplement appeler des méthodes publiques sur le formulaire de tâches sans l’afficher. Malheureusement, la logique de la tâche dépend des opérations de l’événement Form_Load (). Le seul moyen de déclencher Form_Load () consiste à appeler Show (). Le mieux que j’ai pu faire est de montrer le formulaire à l’état minimisé:

 tasksForm.WindowState = FormWindowState.Minimized; tasksForm.Show(); 

Je suppose que la solution la plus propre consisterait à extraire la logique des tâches du formulaire de tâches et à la placer dans une classe de contrôleur. Ensuite, je peux utiliser cette classe à partir du formulaire principal et du formulaire de tâches, et ne charger le formulaire de tâches que lorsque j’ai besoin de le voir pour l’utilisateur. Cependant, s’il est facile de charger le formulaire sans l’afficher, cela constituerait un changement moins important.

Je suis tout à fait d’accord avec Rich B, vous devez regarder où vous placez la logique de votre application plutôt que d’essayer de masquer les mécanismes WinForms. Toutes les opérations et les données exposées par votre formulaire de tâches doivent appartenir à une classe distincte, par exemple un type de contrôleur d’application ou un élément détenu par votre formulaire principal, puis utilisé par votre formulaire de tâches pour lire et afficher les données en cas de besoin. besoin d’un formulaire pour être instancié pour exister.

Il semble probablement difficile de la retravailler, mais vous améliorerez la structure de l’application et la rendre plus facile à gérer, etc.

Il convient peut-être de noter ici que vous pouvez provoquer la création de la fenêtre du formulaire sans afficher le formulaire. Je pense qu’il pourrait y avoir des situations légitimes pour vouloir faire cela.

Quoi qu’il en soit, bon design ou pas, vous pouvez le faire comme ceci:

 MyForm f = new MyForm(); IntPtr dummy = f.Handle; // forces the form Control to be created 

Je ne pense pas que cela provoquera l’appel de Form_Load (), mais vous pourrez appeler f.Invoke () à ce stade (c’est ce que j’essayais de faire lorsque je suis tombé par hasard sur cette question SO).

Il me semble que vous devez vous asseoir et repenser votre approche ici. Je ne peux pas imaginer une seule raison pour laquelle vos méthodes publiques doivent être sous une forme si vous ne voulez pas la montrer. Juste faire une nouvelle classe.

De MSDN:

Form.Load
Se produit avant qu’un formulaire ne soit affiché pour la première fois.

Cela signifie que la seule chose qui entraînerait le chargement du formulaire est son affichage.
Form.Show(); et Form.Visible = true; sont exactement la même chose. Fondamentalement, en arrière-plan, Show vérifie diverses conditions, puis définit Visible sur true. Alors évidemment, régler visible sur false (ce qui est déjà le cas) avant de montrer la forme n’a pas de sens.

Mais oublions les détails techniques. Je suis complètement d’accord avec Rich B et Shaun Austin – la logique ne devrait de toute façon pas être sous cette forme.

Parfois, cela serait utile sans que ce soit une mauvaise conception. Parfois, cela pourrait être le début d’une migration de natif vers géré.

Si vous migriez une application c ++ vers .NET par exemple, vous pouvez simplement transformer votre application en une fenêtre enfant du formulaire ou du panneau .NET, puis migrer progressivement vers le .NET en supprimant le menu de votre application c ++, la barre d’état, barre d’outils et cartographie des .Nt avec votre application via invocation de plate-forme, etc.

Le chargement de votre application C ++ peut prendre un certain temps, mais le formulaire .NET ne vous permet pas de masquer le formulaire .NEt tant que votre application c ++ ne s’est pas initialisée.

Je mettrais l’opacité = 0 et visible = false sur false après l’appel de show, puis, lorsque vous chargez votre application c ++, puis inversez.

Si vous rendez la méthode publique, vous pourrez y accéder directement …. cependant, il pourrait y avoir des effets secondaires inattendus lorsque vous l’appelez. Mais le rendre public et l’appeler directement ne dessine pas l’écran et n’ouvre pas le formulaire.

Déplacez le code d’initialisation obligatoire de la classe de formulaire hors du gestionnaire d’événements Load dans le constructeur. Pour une classe Form, l’instanciation d’une instance (via le constructeur), le chargement et la visibilité de formulaire sont trois choses différentes et ne doivent pas nécessairement se produire en même temps (bien qu’ils doivent évidemment se produire dans cet ordre).

Aucune des réponses n’ayant résolu la question initiale, ajoutez ce qui suit, appelez .Show () pour charger le formulaire sans l’afficher, puis appelez .ShowForm () pour lui permettre d’être visible si vous voulez après:

 private volatile bool _formVisible; protected override void SetVisibleCore(bool value) { base.SetVisibleCore(_formVisible); } public void ShowForm() { _formVisible = true; if (InvokeRequired) { Invoke((Action) Show); } else { Show(); } }