13

When the autogenerated code for my program starts, it calls

Application.Run(new Form1());

and starts Form1. I have another form I'd like to switch to and close Form1 at the same time. The problem is if I use this.Close() in Form1 before I call the other form with Form.ShowDialog() then the program ends. If I put it after ShowDialog then it remains up in the background until I close Form2, at which point the program ends.

How can I spawn a copy of Form2 while closing the currently opened frame at the same time?

Edit: I have tried calling Form2 with .Show() as well, but the new frame closes instantly.

Matt
  • 25,467
  • 18
  • 120
  • 187
rumsey
  • 151
  • 1
  • 2
  • 5

3 Answers3

9

The following solution works as you expect.

To try this sample code, create a new WinForms application in Visual Studio (i.e. File --> New Project, select Visual C# --> Windows Classic Desktop and use the template "Windows Forms App (.NET Framework)"), then add a 2nd form.

Ensure the two forms are named as Form1 and Form2, then modify the code in the generated solution as follows:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        this.FormClosed += 
           new System.Windows.Forms.FormClosedEventHandler(this.Form1_FormClosed);
    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        (new Form2()).Show();
    }
}

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
        this.FormClosed += 
           new System.Windows.Forms.FormClosedEventHandler(this.Form2_FormClosed);
    }

    private void Form2_FormClosed(object sender, FormClosedEventArgs e)
    {
        Application.Exit();
    }
}

And this is the entry point of the application, modify it as follows:

static class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        //Show first form and start the message loop
        (new Form1()).Show();
        Application.Run(); // needed, otherwise app closes immediately
    }

}

The trick is to use Application.Run() without parameters and Application.Exit() at the point where you want to exit the application.

Now when you run the application, Form1 opens up. Click on the X (upper right corner) and Form1 closes, but Form2 appears instead. Click on the X again and the form closes (and exits the application too).

Instead of placing the launch of Form2 into the FormClosed event, you could also create a button Button1 which does the job, but in that case don't forget to close the form to which the button belongs to via this.Close() explicitly:

    private void button1_Click(object sender, EventArgs e)
    {
        (new Form2()).Show(); this.Close();
    }
Matt
  • 25,467
  • 18
  • 120
  • 187
7

You need to call this.Hide() which makes it invisible but still open, instead of this.Close() which closes it (and seeing as it is the main form of the application, closes the application too).

Jackson Pope
  • 14,520
  • 6
  • 56
  • 80
  • If I hide the Form, how do I get back to it from Form2 when I'm done there? I can't called Form1.Show() from inside the Form2 methods? – rumsey May 25 '11 at 18:55
  • 1
    @rumsey: ShowDialog will wait until Form2 is shut, so after the call to ShowDialog(), call this.Show(). – Jackson Pope May 25 '11 at 20:06
  • Just hiding it keeps it in memory, which is ok if you want to re-open it later. Otherwise it is better to close it. – Matt Nov 22 '12 at 21:39
1

Found this question and a codeproject on the same google.

The author basically creates a top-level form that manages switching between the forms he wants to show.

Nathan Goings
  • 1,145
  • 1
  • 15
  • 33