2008-09-15 16 views
9

Kurzversion: Ich möchte das Form_Load() Ereignis auslösen, ohne das Formular sichtbar zu machen. Das funktioniert nicht, weil Show(), um den aktuellen Wert der Eigenschaft Visible ignoriert:Laden Sie ein Formular, ohne es anzuzeigen

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

Lange Version: Ich habe eine WinForms-Anwendung mit zwei Formen: Haupt- und Aufgaben. Das Hauptformular wird immer angezeigt. Der Benutzer kann entweder auf eine Schaltfläche klicken, um das Aufgabenformular zu öffnen, oder auf einige Schaltflächen klicken, die eine Aufgabe direkt ausführen, ohne das Aufgabenformular zu öffnen.

Wenn ein Benutzer fragt, eine Aufgabe direkt auszuführen, möchte ich nur einige öffentliche Methoden auf dem Aufgabenformular aufrufen, ohne es anzuzeigen. Leider hängt die Aufgabenlogik von Dingen ab, die im Form_Load() - Ereignis vorkommen. Die einzige Möglichkeit, Form_Load() auszulösen, besteht darin, Show() aufzurufen. Das Beste, was ich habe in der Lage zu tun ist, um die Form im minimierten Zustand zeigen:

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

ich die sauberste Lösung nehme die Aufgaben Logik aus der Aufgaben Form und in eine Controller-Klasse zu ziehen wäre. Dann kann ich diese Klasse aus dem Hauptformular und aus dem Aufgabenformular verwenden und nur das Aufgabenformular laden, wenn ich es für den Benutzer sichtbar brauche. Wenn es jedoch leicht ist, das Formular zu laden, ohne es anzuzeigen, wäre das eine kleinere Änderung.

+0

Ich ermutige Sie, mit der saubersten Lösung zu gehen. Es wird leichter für Sie sein, später zu warten. –

+0

Wie ich in meiner Antwort gesagt habe und ich stimme mit Scott überein, müssen Sie dies überarbeiten und die Controller-Klassenroute gehen. Es ist eine gute Übung. –

Antwort

7

Ich stimme voll und ganz mit Rich B überein, Sie müssen schauen, wo Sie Ihre Anwendungslogik platzieren, anstatt zu versuchen, die WinForms-Mechanismen zu verklammern. Alle diese Operationen und Daten, die Ihr Aufgabenformular ausstellt, sollten wirklich in einer separaten Klasse sein, sagen Sie eine Art Application Controller oder etwas, das von Ihrem Hauptformular gehalten wird und dann von Ihrem Aufgabenformular verwendet wird, um Daten zu lesen und anzuzeigen, wenn es benötigt wird benötigt ein Formular, das instanziiert werden muss, um zu existieren.

es wahrscheinlich ein Schmerz scheint es zu überarbeiten, aber Sie werden die Struktur der App werden zu verbessern und machen es besser verwaltbar usw.

+1

* seufz * OK, ich werde gut sein. Danke für das Feedback, alle zusammen. –

9

Es klingt für mich wie Sie müssen sich hinsetzen und überdenken Sie Ihren Ansatz hier. Ich kann mir keinen einzigen Grund vorstellen, warum Ihre öffentlichen Methoden in einer Form sein müssen, wenn Sie es nicht zeigen wollen. Mach einfach eine neue Klasse.

+0

Um auf Ihren Punkt zu extrapolieren, haben Sie die Model-Klasse für den Task und die View/Controller-Klasse, die das TaskForm ist. – user7116

+0

@sixlettervariables: Warum sollte er eine Ansicht brauchen? Er sagte, er werde das Formular sowieso nicht laden. Klingt so, als müsste er nur eine Klasse haben. – GEOCHET

+0

Ich habe den Teil verpasst, an dem er nicht einmal die Daten sehen würde. Eine Art von Frage, wenn das die einzige Frage ist ... – user7116

0

Wenn Sie die Methode öffentlich machen, können Sie direkt auf sie zugreifen .... es kann jedoch zu unerwarteten Nebenwirkungen kommen, wenn Sie sie aufrufen. Aber wenn Sie es öffentlich machen und direkt aufrufen, wird der Bildschirm nicht gezeichnet oder das Formular geöffnet.

0

Verschieben Sie den obligatorischen Initialisierungscode für die Formularklasse aus dem Load-Ereignishandler in den Konstruktor. Für eine Form-Klasse sind die Instanziierung einer Instanz (über den Konstruktor), das Laden von Formularen und die Sichtbarkeit von Formularen drei verschiedene Dinge und müssen nicht zur selben Zeit geschehen (obwohl sie offensichtlich in dieser Reihenfolge passieren müssen).

4

Von MSDN:

Form.Load
Tritt auf, bevor ein Formular zum ersten Mal angezeigt wird.

Die einzige Sache, die das Formular laden würde, ist, wenn es angezeigt wird.
Form.Show(); und Form.Visible = true; sind genau das gleiche. Im Grunde überprüft Show im Hintergrund die verschiedenen Bedingungen und setzt Visible auf True. Offensichtlich ist das Setzen von visible auf false (was es bereits ist) vor dem Anzeigen der Form bedeutungslos.

Aber lassen Sie uns die technischen Details vergessen. Ich stimme völlig mit Rich B und Shaun Austin überein - die Logik sollte sowieso nicht in dieser Form sein.

11

Vielleicht sollte hier beachtet werden, dass Sie können verursachen das Fenster des Formulars erstellt werden, ohne das Formular anzuzeigen. Ich denke, dass es legitime Situationen geben könnte, um dies zu tun.

Wie auch immer, ein gutes Design oder nicht, Sie dass, wie dies tun:

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

Ich glaube nicht das Form_Load verursachen wird() aufgerufen werden, aber Sie werden in der Lage f.Invoke anrufen() An diesem Punkt (was ich versuchte zu tun, als ich auf diese Frage stieß).

+0

Diese Antwort hat mir sehr geholfen. – Kelsie

+0

Ein Grund ist, die App wie einen Dienst laufen zu lassen –

1

Manchmal wäre dies ohne ein schlechtes Design nützlich. Manchmal könnte es der Beginn einer Migration von nativ zu verwaltet sein. Wenn Sie beispielsweise eine C++ - App nach .NET migrieren, können Sie einfach Ihre gesamte App in ein untergeordnetes Fenster des .NET-Formulars oder -Fensters verwandeln und nach und nach auf .NET umstellen, indem Sie Ihr C++ App-Menü loswerden , Statusleiste, Symbolleiste und Zuordnung der .NEt zu Ihrer App mit Plattform aufrufen etc ...

Ihre C++ App kann eine Weile dauern, um zu laden, aber die .NET-Form nicht .. in denen Sie mögen um das .NEt-Formular auszublenden, bis sich Ihre C++ - App initialisiert hat.

Ich würde opacity = 0 und visible = false auf false nach dem Aufruf von show setzen, dann, wenn Ihre C++ App lädt, dann rückwärts.

Verwandte Themen