c # ein neues Formular öffnen und dann das aktuelle Formular schließen?


89

Angenommen, ich bin in Form 1, dann möchte ich:

  1. Öffnen Sie Formular 2 (über eine Schaltfläche in Formular 1).
  2. Formular 1 schließen
  3. Konzentrieren Sie sich auf Form 2

18
Schreckliche Benutzerfreundlichkeit. Wenn Sie WinForms verwenden, erstellen Sie einfach ein Containerfenster und ersetzen Sie stattdessen die Bedienfelder. Ihre Benutzer werden Sie dafür lieben (und Sie dafür hassen, dass Sie es nicht tun)
Claus Jørgensen

1
Hör auf Claus! Was Sie erreichen möchten, ist möglicherweise a) eine Winforms-Implementierung einer assistentenähnlichen sequentiellen Reihe von Schritten oder b) ein Versuch, ein "Ergebnis" -Formular nach einem "Dateneingabe- / Übermittlungs" -Formular anzuzeigen. Unabhängig davon, ob es sich um a) oder b) handelt, ist das UI-Verhalten, das Sie implementieren möchten, eine suboptimale Lösung.
Simen S

Vielen Dank an Clause und Simen S. Ihre Kommentare sind für einen Anfänger wie mich sehr hilfreich. Ich werde weitere Tutorials über GUI und Benutzerfreundlichkeit lesen. Könnten Sie mir einige nützliche empfehlen?
tnhan07


Überprüfen Sie auch [Antworten hier] ( stackoverflow.com/questions/4759334/… ), ob Ihre eigentliche Absicht darin bestand, nur ein Anmeldeformular (oder ein ähnliches Formular) zu haben.
Ilias Iliadis

Antworten:


193

Steves Lösung funktioniert nicht. Beim Aufruf von this.Close () wird das aktuelle Formular zusammen mit form2 entsorgt. Daher müssen Sie es ausblenden und das Ereignis form2.Closed festlegen, um this.Close () aufzurufen.

private void OnButton1Click(object sender, EventArgs e)
{
    this.Hide();
    var form2 = new Form2();
    form2.Closed += (s, args) => this.Close(); 
    form2.Show();
}

2
In Windows-Formularen im Punktnetz gibt es kein geschlossenes Ereignis. Können Sie mir sagen, ist es FormClosed Ereignis
Anjali

2
Hält das Ausblenden des ersten Formulars es nicht noch im Gedächtnis? Wie können wir diese Ressource freigeben?
user2635088

5
form2.Closed += (s, args) => this.Close();Darf ich wissen, wie diese Aussage funktioniert? was genau (s,args)ist
Yash Saraiya

1
(s, args) => this.Close();ist ein Lambda-Ausdruck. Es wird eine Funktion "an Ort und Stelle" erstellt, die beim form2.ClosedAuslösen des Ereignisses aufgerufen wird. (s, args)sind nur Namen für die Parameter zum Lambda. Was für einen Event-Handler normalerweise so etwas ist (object sender, EventArgs e). Da die ClosedSignatur des Ereignisdelegierten ihre Typen beschreibt, werden die Typen nicht angegeben (jemand korrigiert gegebenenfalls meinen Wortlaut). // Insgesamt ist es nur eine schwierige Möglichkeit, nicht eine ganze Funktion (Ereignishandler) außerhalb der aktuellen Funktion deklarieren zu müssen, die das Form2.ClosedEreignis behandelt.
KDecker

1
Es versteckt nur die erste Form und öffnet die neue Form, schließt aber nicht die erste Form
Uddyan Semwal

25

Versuchen Sie dies zu tun ...

{
    this.Hide();
    Form1 sistema = new Form1();
    sistema.ShowDialog();
    this.Close();
}

Hier ist das Ding. Ich habe ein Hauptformular. aber ich benutze ein kleines Formular für einen Login. Dieses Formular ruft das Hauptformular mit dieser Methode auf. Ok, wir sind gut hier. Das Problem war, wenn das Hauptformular ein untergeordnetes Formular anzeigt und beim Schließen des untergeordneten Formulars auch das Hauptformular geschlossen wird. Also da verwende ich die von Nihique veröffentlichte Methode. Der Code hat so gut funktioniert! ...
MontDeska

Dieser Code funktioniert für mich. Ich benutze VS 2015. Danke
IT Vlogs

21

In den anderen Antworten wurden bereits viele verschiedene Möglichkeiten beschrieben. Viele von ihnen sind jedoch entweder beteiligt ShowDialog()oder form1bleiben offen, aber verborgen. Der beste und intuitivste Weg ist meiner Meinung nach, einfach zu schließen form1und dann form2von einem externen Ort aus zu erstellen (dh nicht von innerhalb einer dieser Formen). In dem Fall, in dem form1in erstellt wurde Main, form2kann einfach mit Application.Runwie form1zuvor erstellt werden. Hier ist ein Beispielszenario:

Der Benutzer muss seine Anmeldeinformationen eingeben, damit ich sie irgendwie authentifizieren kann. Wenn die Authentifizierung erfolgreich war, möchte ich dem Benutzer anschließend die Hauptanwendung anzeigen. Um dies zu erreichen, verwende ich zwei Formen: LogingFormund MainForm. Das LoginFormhat ein Flag, das bestimmt, ob die Authentifizierung erfolgreich war oder nicht. Dieses Flag wird dann verwendet, um zu entscheiden, ob die MainFormInstanz erstellt werden soll oder nicht. Keines dieser Formulare muss etwas über das andere wissen, und beide Formulare können ordnungsgemäß geöffnet und geschlossen werden. Hier ist der Code dafür:

class LoginForm : Form
{
    public bool UserSuccessfullyAuthenticated { get; private set; }

    void LoginButton_Click(object s, EventArgs e)
    {
        if(AuthenticateUser(/* ... */))
        {
            UserSuccessfullyAuthenticated = true;
            Close();
        }
    }
}

static class Program
{
    [STAThread]
    static void Main()
    {
        LoginForm loginForm = new LoginForm();
        Application.Run(loginForm);

        if(loginForm.UserSuccessfullyAuthenticated)
        {
            // MainForm is defined elsewhere
            Application.Run(new MainForm());
        }
    }
}

Dies ist ein schöner Trick, als Formen zu verstecken. Wenn wir ausgeblendete Formulare haben, um die Anwendung zu beenden, reicht es nicht aus, das aktuelle Formular zu schließen. Wir müssen Application.Exit (0) usw. verwenden.
Peck_conyon

Es ist schön, aber ich denke, es ist nur für 2 Formen geeignet. Was ist mit mehreren Formen, die zwischen ihnen wechseln?
Dr. MAF

Dies ist darauf beschränkt, Formulare nacheinander auszuführen, nicht parallel oder übereinander, wie vom OP gefordert. Ich bin mir nicht sicher, warum dies nur auf zwei Formen beschränkt ist. Der externe Code kann beliebig viele Formulare nacheinander erzeugen. Das Umschalten zwischen ihnen kann auch durch den externen Code erfolgen. Es kann einen Status im Hauptformular (wie loginForm.UserSuccessfullyAuthenticatedzuvor) oder einen globalen Status überprüfen , um zu entscheiden, ob das Anmeldeformular erneut ausgeführt oder ein anderes Formular ausgeführt oder der Prozess beendet werden soll.
Manuzor

11

Das Problem besteht in dieser Zeile:

Application.Run(new Form1()); Was wahrscheinlich in Ihrer Datei program.cs zu finden ist.

Diese Zeile gibt an, dass form1 die Nachrichtenschleife behandeln soll - mit anderen Worten, form1 ist dafür verantwortlich, Ihre Anwendung weiterhin auszuführen - die Anwendung wird geschlossen, wenn form1 geschlossen wird.

Es gibt verschiedene Möglichkeiten, damit umzugehen, aber alle auf die eine oder andere Weise schließen form1 nicht.
(Es sei denn, wir ändern den Projekttyp in etwas anderes als die Windows Forms-Anwendung.)

Das, was meiner Meinung nach für Ihre Situation am einfachsten ist, besteht darin, drei Formulare zu erstellen:

  • form1 - bleibt unsichtbar und fungiert als Manager. Sie können es einem Tray-Symbol zuweisen, wenn Sie möchten.

  • form2 - hat die Schaltfläche, die beim Klicken form2 schließt und form3 öffnet

  • form3 - hat die Rolle des anderen Formulars, das geöffnet werden muss.

Und hier ist ein Beispielcode, um dies zu erreichen:
(Ich habe auch ein Beispiel hinzugefügt, um die App aus dem 3. Formular zu schließen.)

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1()); //set the only message pump to form1.
    }
}


public partial class Form1 : Form
{
    public static Form1 Form1Instance;

    public Form1()
    {
        //Everyone eveywhere in the app should know me as Form1.Form1Instance
        Form1Instance = this;

        //Make sure I am kept hidden
        WindowState = FormWindowState.Minimized;
        ShowInTaskbar = false;
        Visible = false;

        InitializeComponent();

        //Open a managed form - the one the user sees..
        var form2 = new Form2();
        form2.Show();
    }

}

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var form3 = new Form3(); //create an instance of form 3
        Hide();             //hide me (form2)
        form3.Show();       //show form3
        Close();            //close me (form2), since form1 is the message loop - no problem.
    }
}

public partial class Form3 : Form
{
    public Form3()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Form1.Form1Instance.Close(); //the user want to exit the app - let's close form1.
    }
}


Hinweis: Das dynamische Arbeiten mit Bedienfeldern oder das dynamische Laden von Benutzersteuerelementen ist akademischer und als Produktionsstandard der Branche vorzuziehen. Mir scheint jedoch, Sie versuchen nur zu überlegen, wie die Dinge funktionieren. Zu diesem Zweck ist dieses Beispiel besser.

Und jetzt, da die Prinzipien verstanden sind, versuchen wir es mit nur zwei Formen:

  • Das erste Formular übernimmt die Rolle des Managers wie im vorherigen Beispiel, zeigt jedoch auch den ersten Bildschirm an, sodass es nicht nur ausgeblendet geschlossen wird.

  • Das zweite Formular übernimmt die Rolle des nächsten Bildschirms und durch Klicken auf eine Schaltfläche wird die Anwendung geschlossen.


    public partial class Form1 : Form
    {
        public static Form1 Form1Instance;

        public Form1()
        {
            //Everyone eveywhere in the app show know me as Form1.Form1Instance
            Form1Instance = this;
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //Make sure I am kept hidden
            WindowState = FormWindowState.Minimized;
            ShowInTaskbar = false;
            Visible = false;

            //Open another form 
            var form2 = new Form2
            {
                //since we open it from a minimezed window - it will not be focused unless we put it as TopMost.
                TopMost = true
            };
            form2.Show();
            //now that that it is topmost and shown - we want to set its behavior to be normal window again.
            form2.TopMost = false; 
        }
    }

    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form1.Form1Instance.Close();
        }
    }

Wenn Sie das vorherige Beispiel ändern, löschen Sie form3 aus dem Projekt.

Viel Glück.


6

Sie waren nicht spezifisch, aber es sieht so aus, als hätten Sie versucht, das zu tun, was ich in meinen Win Forms-Apps mache: Beginnen Sie mit einem Anmeldeformular, schließen Sie dieses Formular nach erfolgreicher Anmeldung und konzentrieren Sie sich auf ein Hauptformular. So mache ich das:

  1. mache frmMain zum Startformular; So sieht meine Program.cs aus:

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new frmMain());
    }
    
  2. Erstellen Sie in meinem frmLogin eine öffentliche Eigenschaft, die auf false initialisiert und nur dann auf true gesetzt wird, wenn eine erfolgreiche Anmeldung erfolgt:

    public bool IsLoggedIn { get; set; }
    
  3. mein frmMain sieht so aus:

    private void frmMain_Load(object sender, EventArgs e)
    {
        frmLogin frm = new frmLogin();
        frm.IsLoggedIn = false;
        frm.ShowDialog();
    
        if (!frm.IsLoggedIn)
        {
            this.Close();
            Application.Exit();
            return;
        }
    

Kein erfolgreicher Login? Beenden Sie die Anwendung. Andernfalls fahren Sie mit frmMain fort. Da es sich um das Startformular handelt, wird die Anwendung beim Schließen beendet.


3

Verwenden Sie dieses Code-Snippet in Ihrem Formular1.

public static void ThreadProc()
{
Application.Run(new Form());
}

private void button1_Click(object sender, EventArgs e)
{
System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(ThreadProc));
t.Start();
this.Close();
}

Ich habe das von hier bekommen


Beachten Sie, dass von Antworten nur mit Links abgeraten wird. SO-Antworten sollten der Endpunkt einer Suche nach einer Lösung sein (im Gegensatz zu einem weiteren Zwischenstopp von Referenzen, die im Laufe der Zeit veralten). Bitte fügen Sie hier eine eigenständige Zusammenfassung hinzu, wobei Sie den Link als Referenz behalten.
Kleopatra

2

Wenn Sie zwei Formulare haben: frm_form1 und frm_form2. Der folgende Code wird verwendet, um frm_form2 zu öffnen und frm_form1 zu schließen. (Für Windows-Formularanwendung)

        this.Hide();//Hide the 'current' form, i.e frm_form1 
        //show another form ( frm_form2 )   
        frm_form2 frm = new frm_form2();
        frm.ShowDialog();
        //Close the form.(frm_form1)
        this.Close();

1

Normalerweise mache ich das, um zwischen Formen hin und her zu wechseln.

Erstens behalte ich in der Programmdatei ApplicationContext und füge eine Helfer- SwitchMainForm- Methode hinzu.

        static class Program
{
    public static ApplicationContext AppContext { get;  set; }


    static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        //Save app context
        Program.AppContext = new ApplicationContext(new LoginForm());
        Application.Run(AppContext);
    }

    //helper method to switch forms
      public static void SwitchMainForm(Form newForm)
    {
        var oldMainForm = AppContext.MainForm;
        AppContext.MainForm = newForm;
        oldMainForm?.Close();
        newForm.Show();
    }


}

Dann rufe ich jetzt irgendwo im Code die SwitchMainForm- Methode auf, um einfach zum neuen Formular zu wechseln.

// switch to some other form
var otherForm = new MyForm();
Program.SwitchMainForm(otherForm);

0
private void buttonNextForm(object sender, EventArgs e)
{
    NextForm nf = new NextForm();//Object of the form that you want to open
    this.hide();//Hide cirrent form.
    nf.ShowModel();//Display the next form window
    this.Close();//While closing the NextForm, control will come again and will close this form as well
}

Es wird nicht funktionieren. Es macht keinen Sinn, sich zu verstecken, bevor das nächste Formular angezeigt wird. Es wird sametime ausgeführt und das Programm wird beendet.
Ahmet Karabulut

0
//if Form1 is old form and Form2 is the current form which we want to open, then
{
Form2 f2 = new Form1();

this.Hide();// To hide old form i.e Form1
f2.Show();
}


0
                     this.Visible = false;
                        //or                         // will make LOgin Form invisivble
                        //this.Enabled = false;
                         //  or
                       // this.Hide(); 



                        Form1 form1 = new Form1();
                        form1.ShowDialog();

                        this.Dispose();

1
Was ist mit dieser Antwort, die zu dieser Diskussion beiträgt? Es wird wiederholt, ohne dass in den 9 anderen Antworten Erklärungsinformationen hinzugefügt werden.
Edward

0

Ich denke das ist viel einfacher :)

    private void btnLogin_Click(object sender, EventArgs e)
    {
        //this.Hide();
        //var mm = new MainMenu();
        //mm.FormClosed += (s, args) => this.Close();
        //mm.Show();

        this.Hide();
        MainMenu mm = new MainMenu();
        mm.Show();

    }

Diese Lösung ist keine verwandte Antwort auf diese Frage. Ihre Lösung schließt das aktuelle Formular nicht. Dies bedeutet, dass das aktuelle Formular noch in Bearbeitung ist.
Ahmet Karabulut

-1

Angenommen, Sie haben zwei Formulare, der erste Formularname ist Form1 und der zweite Formularname ist Form2. Sie müssen hier von Form1 zu Form2 springen und Code eingeben. Schreiben Sie den folgenden Code:

Auf Form1 habe ich eine Schaltfläche mit dem Namen Button1, und auf der Klickoption schreiben Sie den folgenden Code:

protected void Button1_Click(Object sender,EventArgs e)
{
    Form frm=new Form2();// I have created object of Form2
    frm.Show();
    this.Visible=false;
    this.Hide();
    this.Close();
    this.Dispose();
}

Hoffe, dieser Code wird Ihnen helfen


Diese vier Methoden: this.Visible=false; this.Hide(); this.Close(); this.Dispose();sind redundant. Du brauchst nichts mehr als Close(). Durch das Schließen eines Formulars wird es entsorgt. Das Festlegen der Sichtbarkeit des Formulars entspricht dem Ausblenden. Das Ausblenden eines Formulars ist sinnlos, wenn es vor dem nächsten Malereignis nicht vorhanden sein wird.
Servy

-3

Ich würde es lösen, indem ich:

private void button1_Click(object sender, EventArgs e)
{
    Form2 m = new Form2();
    m.Show();
    Form1 f = new Form1();
    this.Visible = false;
    this.Hide();
}

3
this.Visible = falseund dann this.Hide? Warum zweimal dasselbe tun?
Neolisk

8
Warum erschaffst du ein neues Form1und machst nichts damit?
Servy
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.