Was ist der Unterschied zwischen Application.Run () und Form.ShowDialog ()?

72

In meiner Bewerbung möchte ich zuerst ein Anmeldeformular und dann das Hauptformular anzeigen, wenn die Anmeldung erfolgreich war. Momentan mache ich so etwas:

var A = new LoginForm();
if ( A.ShowDialog() == DialogResult.OK )
    Application.Run(new MainForm());

Aber dann begann ich mich zu fragen - was ist der Sinn des Application.Run()? Warum nicht einfach so machen (new MainForm()).ShowDialog()? Was ist der Unterschied? Und was wäre der richtige Weg, um das zu erreichen, was ich will?

Vilx-
quelle

Antworten:

67

Application.Run(Form)Startet eine Nachrichtenschleife für den aktuellen Thread und zeigt das angegebene Formular an. Die Nachrichtenschleife ermöglicht es dem Formular, Windows-Nachrichten zu empfangen (z. B. Tastendruck, Mausklicks, Ungültigmachungen beim Malen), damit es reaktionsschnell erscheint und mit dem Benutzer interagiert. Wenn Sie ShowDialog()eine FormInstanz aufrufen , funktioniert dies ähnlich und es wird eine modale Nachrichtenschleife für das Formular erstellt, auf dem ShowDialogaufgerufen wurde.

Es gibt keinen großen Unterschied zwischen den beiden Anrufen. Application.RunFügt eine zusätzliche Ereignisbehandlung hinzu, mit der Sie Ressourcen aufräumen können, wenn das Hauptformular geschlossen wird (siehe Application.ThreadExit ).

Die empfohlene Methode zum Starten von WinForms-Anwendungen ist die Verwendung Application.Run, aber ich vermute, dass dies eher eine Konvention als eine Regel ist. Der Hauptgrund für die Verwendung Application.Runist, wenn Sie mehrere nicht modale Formulare öffnen möchten. Sie können dies tun mit:

new Form().Show();
new Form().Show();
Application.Run();

Sie konnten dies mit der ShowDialog()Methode nicht erreichen , da eine der Formen modal sein müsste.


Was Ihre Frage betrifft, wie ein Anmeldeformular und dann das Hauptformular angezeigt werden soll, wenn die Anmeldung erfolgreich ist, denke ich, dass das, was Sie haben, in Ordnung ist:

if (new LoginForm().ShowDialog() == DialogResult.OK)
{
    Application.Run(new MainForm());
}

Die Alternative besteht darin, die Installation selbst durchzuführen und eine Instanz von MainFormim Abschlussereignis zu öffnen, LoginFormwenn die Anmeldung erfolgreich war.

adrianbanks
quelle
Das bedeutet also, dass Sie eine Nachrichtenschleife im selben Thread wie die beiden Formulare haben können, während Sie die drei getrennt behandeln können?
SomeNickName
5

Von MSDN:

Diese Methode fügt dem mainForm-Parameter für das Closed-Ereignis einen Ereignishandler hinzu. Der Ereignishandler ruft ExitThread auf, um die Anwendung zu bereinigen.

http://msdn.microsoft.com/en-us/library/ms157902.aspx

BKostenlos
quelle
7
Ist das der einzige bemerkenswerte Unterschied? Ich habe beim Reflektor nachgefragt und es scheint, dass hinter den Kulissen viel mehr passiert, je nachdem, welcher aufgerufen wurde. Es gibt definitiv subtilere Unterschiede, obwohl ich nicht sagen kann, was - der reflektierte Code ist ziemlich kryptisch.
Vilx
1
Ich habe gerade einen Verrückten gefunden und bin hier angekommen, während ich gegoogelt habe, um zu sehen, ob jemand erklären kann, warum: Ich habe heute etwa eine Stunde bei der Arbeit verbracht, um herauszufinden, warum dies.Hide () und this.Visible = false in meinem Formular Beide schlossen das Formular tatsächlich, anstatt es zu verstecken. Ich war total verblüfft. Anscheinend gibt es einen Unterschied - vollständig reproduzierbar! - wo form.ShowDialog () dies tut, aber Application.Run () das erwartete tut. Was ist damit los? (Ich denke, die Idee ist, weil es modal ist, wenn es jemals nicht angezeigt wird, wird angenommen, dass Sie es schließen möchten.)
neminem
5

Bei meinen Tests habe ich diesen Hauptunterschied festgestellt:

Wenn Application.Run verwendet wird, gibt die Schaltfläche Schließen (rotes X) des Formulars DialogResult.None zurück. Wenn jedoch ShowDialog verwendet wird, erzeugt die Schaltfläche Schließen DialogResult.Cancel.

Ist dir das wichtig? In meinem Code habe ich auf DialogResult.Cancel getestet, um den Exit-Code meiner Anwendung zu ermitteln. Das war kaputt, als das rote X zum Schließen des Formulars verwendet wurde. Ich teste jetzt auf DialogResult.OK, um einen erfolgreichen Exit anzuzeigen.

        return myForm.DialogResult == DialogResult.OK ? 0 : 1;
John
quelle
1
Dies ist wegen Application.Run verwendet die Form.Show ()
Soroush Falahati
2

Ein wesentlicher Unterschied besteht darin, dass ShowDialog normalerweise ein modaler Dialog ist. Wenn Sie ein benutzerfreundliches Toolset erstellen möchten, möchten Sie nicht, dass es aus modalen Dialogfeldern besteht.

Außerdem akzeptiert Application.Run () mehr als nur ein Formular. Es hat ein paar Überlastungen.

Was Ihre Bewerbung betrifft, denke ich nicht, dass es wichtig ist. Application.Run ist für mich sinnvoll, da es den Start Ihrer eigentlichen Anwendung kennzeichnet.

Chad Stewart
quelle
Da es meine Hauptform ist, spielt es keine Rolle, ob es sich um einen modalen Dialog handelt, oder?
Vilx
2

Die Dokumentation der Überlastung

public static void Run(
    ApplicationContext context );

hat ein ordentliches Beispiel mit einem anderen Ansatz, der auch zwei Formen umfasst.

Uwe Keim
quelle
1
Guter Tipp. Leider hat es mir nicht geholfen, da ich WinCE benutze.
Oren
2

Für ein konkreteres Beispiel eines Unterschieds:

Wenn es sich bei Ihrem Hauptformular um ein MDI-Formular handelt, unterscheidet sich das Verhalten beim Klicken auf die Schaltfläche zum Schließen (das 'x' oben rechts oder Alt-F4) je nachdem, mit welcher Methode Sie das Formular anzeigen.

Wenn Application.Run(mainForm)das Abschlussereignis der untergeordneten Formulare ausgeführt wird, wird das Abschlussereignis des Hauptformulars ausgeführt.

Mit mainForm.ShowDialogwird das Abschlussereignis des Hauptformulars ausgeführt, und das Abschlussereignis der untergeordneten Formulare wird nicht ausgeführt.

jswolf19
quelle
1

Application.Run()ist für den Start der Anwendung vorgesehen, während sie MainFormTeil der Anwendung ist und MainForm()).ShowDialog()nur zur Anzeige verwendet wird.

Application.Run()ist das entry pointfür Ihre Bewerbung. Die gleiche Main()Methode gilt für eine Klasse oder ApplicationStart()eine Webanwendung

Application.Run () hat verschiedene Überladungen, von denen eine ohne Parameter ist. Diese Methode startet die Anwendung ohne ein erstes Formular.

Asad
quelle
1
Was bedeutet das alles für das, was ich wählen soll? Bisher scheint mir, dass beide Wege gut funktionieren. Aber es muss einige subtile Unterschiede geben, oder?
Vilx
0

Bei meinen Tests habe ich festgestellt, dass die Verwendung von Application.Run-Schaltflächen mit DialogResult das Formular nicht schließt (OnFormClosing wird nicht getroffen), verglichen mit ShowDialog, bei dem die Schaltflächen mit DialogResult OnFormClosing treffen und das Formular schließen.

Tomas Kubes
quelle