112

For example, Assume that I'm in form 1 then I want:

  1. Open form 2( from a button in form 1)
  2. Close form 1
  3. Focus on form 2
tnhan07
  • 1,167
  • 2
  • 8
  • 6
  • 23
    Terrible usability. If you're using WinForms, then just create a container window, and replace the panels instead. Your users will love you for it (and hate you for not doing it) – Claus Jørgensen Apr 05 '11 at 07:56
  • 1
    Listen to Claus! What you trying to achieve is perhaps a) A winforms implementation of a wizard-like sequential series of steps or b) An attempt to show a "result"-form after a "data entry/submit" form. Regardless of whether it is a) or b) the UI behaviour that you are attempting to implement is a suboptimal solution. – Simen S Apr 05 '11 at 09:20
  • Thanks Clause and Simen S very much. Your comments are very helpful for a beginner like me. I'll read more tutorials about GUI and usability. Could you recommend me some useful ones? – tnhan07 Apr 06 '11 at 15:44
  • 1
    http://stackoverflow.com/a/10769349/17034 – Hans Passant Jan 15 '16 at 15:20
  • Check also [answers here] (https://stackoverflow.com/questions/4759334/how-can-i-close-a-login-form-and-show-the-main-form-without-my-application-closi), if your real intend was just to have a login (or alike) form. – ilias iliadis Feb 15 '19 at 22:28

17 Answers17

216

Steve's solution does not work. When calling this.Close(), current form is disposed together with form2. Therefore you need to hide it and set form2.Closed event to call this.Close().

private void OnButton1Click(object sender, EventArgs e)
{
    this.Hide();
    var form2 = new Form2();
    form2.Closed += (s, args) => this.Close(); 
    form2.Show();
}
nihique
  • 5,738
  • 2
  • 25
  • 27
  • 2
    there is no Closed event in windows forms in dot net. Can you tell me is it FormClosed event – Anjali Jul 11 '14 at 09:47
  • This works but one shouldnt really be using this way of switching between forms! – Rick Roy Jul 12 '14 at 10:00
  • @nihique to quote G.Y it is wrong coz "Note: working with panels or loading user-controls dynamically is more academic and preferable as industry production standards - but it seems to me you just trying to reason with how things work - for that purpose this example is better." – Rick Roy Jul 16 '14 at 03:14
  • 2
    Doesn't hiding the first form still keep it memory? How can we release that resource? – user2635088 Nov 11 '15 at 09:53
  • 5
    `form2.Closed += (s, args) => this.Close();` May I know how does this statement work? what exactly `(s,args)` is? – Yash Saraiya Jan 04 '16 at 07:28
  • 1
    `(s, args) => this.Close();` is a lambda expression. It creates a function "in place" that is called when the `form2.Closed` event is fired. `(s, args)` are just names for the parameters to the lambda. Which for an event handler are usually something like `(object sender, EventArgs e)`. Because the `Closed` event delegate signature describes their types, the types are not given (Someone please correct my wording if need be). // Overall its just a tricky way to not have to declare an entire function (event handler) outside of the current one that handles `Form2.Closed` event. – KDecker Mar 21 '16 at 12:53
  • For me this ended up with a loop calling this.Close() over and over again. – ds99jove May 06 '16 at 05:55
  • 1
    its just hiding first form and opening new form but not closing first form – Uddyan Semwal Sep 05 '19 at 08:24
35

Many different ways have already been described by the other answers. However, many of them either involved ShowDialog() or that form1 stay open but hidden. The best and most intuitive way in my opinion is to simply close form1 and then create form2 from an outside location (i.e. not from within either of those forms). In the case where form1 was created in Main, form2 can simply be created using Application.Run just like form1 before. Here's an example scenario:

I need the user to enter their credentials in order for me to authenticate them somehow. Afterwards, if authentication was successful, I want to show the main application to the user. In order to accomplish this, I'm using two forms: LogingForm and MainForm. The LoginForm has a flag that determines whether authentication was successful or not. This flag is then used to decide whether to create the MainForm instance or not. Neither of these forms need to know about the other and both forms can be opened and closed gracefully. Here's the code for this:

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());
        }
    }
}
Peck_conyon
  • 221
  • 2
  • 13
Manuzor
  • 1,746
  • 1
  • 18
  • 19
  • This is a nice trick than hiding forms. When we have hidden forms to exit the application it is not just enough by closing the current form. We have to use Application.Exit(0) etc. – Peck_conyon Apr 03 '20 at 11:02
  • It's nice, but I think it is suitable for only 2 forms. What about multiple forms switching between them?? – Dr. MAF Jul 21 '20 at 22:18
  • This is restricted to running forms in sequence, not in parallel or on top of each other, as the OP asked. I'm not sure why this would be restricted to only 2 forms, though. The outside code is free to spawn as many forms in sequence as desired. Toggling between them can also be done by the outside code. It could check some state on the main form (like `loginForm.UserSuccessfullyAuthenticated` before) or maybe global state to decide whether to re-run the login form, or run another form, or maybe terminate the process. – Manuzor Jul 27 '20 at 15:04
  • I like this method. It's elegant and simple to implement. The top voted answer is a quick and dirty way to accomplish the same end goals but caused me issues in the long run dealing with cleaning up resources etc. Great job @Manuzor. – Arvo Bowen Feb 28 '23 at 20:52
33

Try to do this...

{
    this.Hide();
    Form1 sistema = new Form1();
    sistema.ShowDialog();
    this.Close();
}
Raging Bull
  • 18,593
  • 13
  • 50
  • 55
MontDeska
  • 1,617
  • 19
  • 16
  • Here is the thing. I have a Main Form. but I use a little form for a Login. This form calls the Main Form with this method. Ok we are good here. The problem was when the Main Form shows a child Form, and at closing the child form... it Closes the Main Form too. So Since I am using the method published by Nihique. The code have been working so nice!... – MontDeska Nov 30 '12 at 06:10
  • this code is working for me. i am using VS 2015. Thanks – Dũng IT Nov 10 '18 at 07:11
12

The problem beings with that line:

Application.Run(new Form1()); Which probably can be found in your program.cs file.

This line indicates that form1 is to handle the messages loop - in other words form1 is responsible to keep executing your application - the application will be closed when form1 is closed.

There are several ways to handle this, but all of them in one way or another will not close form1.
(Unless we change project type to something other than windows forms application)

The one I think is easiest to your situation is to create 3 forms:

  • form1 - will remain invisible and act as a manager, you can assign it to handle a tray icon if you want.

  • form2 - will have the button, which when clicked will close form2 and will open form3

  • form3 - will have the role of the other form that need to be opened.

And here is a sample code to accomplish that:
(I also added an example to close the app from 3rd form)

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.
    }
}


Note: working with panels or loading user-controls dynamically is more academic and preferable as industry production standards - but it seems to me you just trying to reason with how things work - for that purpose this example is better.

And now that the principles are understood let's try it with just two forms:

  • The first form will take the role of the manager just like in the previous example but will also present the first screen - so it will not be closed just hidden.

  • The second form will take the role of showing the next screen and by clicking a button will close the application.


    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();
        }
    }

If you alter the previous example - delete form3 from the project.

Good Luck.

G.Y
  • 6,042
  • 2
  • 37
  • 54
7

You weren't specific, but it looks like you were trying to do what I do in my Win Forms apps: start with a Login form, then after successful login, close that form and put focus on a Main form. Here's how I do it:

  1. make frmMain the startup form; this is what my Program.cs looks like:

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new frmMain());
    }
    
  2. in my frmLogin, create a public property that gets initialized to false and set to true only if a successful login occurs:

    public bool IsLoggedIn { get; set; }
    
  3. my frmMain looks like this:

    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;
        }
    

No successful login? Exit the application. Otherwise, carry on with frmMain. Since it's the startup form, when it closes, the application ends.

Barry Novak
  • 99
  • 1
  • 6
3

use this code snippet in your form1.

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();
}

I got this from here

lakshman
  • 2,641
  • 6
  • 37
  • 63
  • Note that link-only answers are discouraged, SO answers should be the end-point of a search for a solution (vs. yet another stopover of references, which tend to get stale over time). Please consider adding a stand-alone synopsis here, keeping the link as a reference. – kleopatra Jul 21 '13 at 14:21
3

If you have two forms: frm_form1 and frm_form2 .The following code is use to open frm_form2 and close frm_form1.(For windows form application)

        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();
maneesh
  • 919
  • 8
  • 6
1

I usually do this to switch back and forth between forms.

Firstly, in Program file I keep ApplicationContext and add a helper SwitchMainForm method.

        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();
    }


}

Then anywhere in the code now I call SwitchMainForm method to switch easily to the new form.

// switch to some other form
var otherForm = new MyForm();
Program.SwitchMainForm(otherForm);
Namig Hajiyev
  • 1,117
  • 15
  • 16
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
}
Prateek Shukla
  • 593
  • 2
  • 7
  • 27
  • It won't work. There is no sense to hide before showing the next form. It will executed sametime and program will be terminated. – Ahmet Karabulut Mar 30 '18 at 14:59
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();
}
fedorqui
  • 275,237
  • 103
  • 548
  • 598
0

This code may help you:

Master frm = new Master();

this.Hide();

frm.ShowDialog();

this.Close();
Baby Groot
  • 4,637
  • 39
  • 52
  • 71
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
    What about this answer adds to this discussion? It is restating without adding any explanation info present in the 9 other answers. – Edward Sep 11 '13 at 18:38
0

I think this is much easier :)

    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();

    }
Sachith Wickramaarachchi
  • 5,546
  • 6
  • 39
  • 68
  • This solution is not a related answer for this question. Your solution will not close current form, this mean current form still in process. – Ahmet Karabulut Mar 30 '18 at 14:58
0

Everyone needs to participate in this topic :). I want to too! I used WPF (Windows Presentation Foundation) to close and open windows. How I did:

  1. I used clean code, so I deleted App.xaml and create Program.cs
  2. Next, a window manager was created
  3. The program analyzes the keys and the manager can launch either 1 window or 2 windows (1 informational, then when the button is pressed, it closes and a new main window 2 opens)
internal class Program
{
    [STAThread]
    public static void Main(string[] args)
    {
        Mgm mgm = new Mgm(args);
        mgm.SecondaryMain();
    }
}

internal class Mgm
{
    private Dictionary<string, string> argsDict = new Dictionary<string, string>();

    private InformWindow iw = null;
    private MainWindow mw = null;
    private Application app = null;

    public Mgm(string[] args)
    {
        CheckInputArgs(args);
    }

    private void CheckInputArgs(string[] strArray)
    {
        if (strArray.Length == 0)
            return;

        for (int i = 0; i < strArray.Length; i++)
        {
            if (strArray[i].StartsWith("-") && !argsDict.ContainsKey(strArray[i]))
                argsDict.Add(strArray[i], null);
            else
                if (i > 0 && strArray[i - 1].StartsWith("-"))
                    argsDict[strArray[i - 1]] = strArray[i];
        }
    }

    public void SecondaryMain()
    {
        if (!argsDict.ContainsKey("-f"))
            return;

        if (argsDict.ContainsKey("-i"))
        {
            if (String.IsNullOrEmpty(argsDict["-i"]) || !int.TryParse(argsDict["-i"], out _))
                iw = new InformWindow();
            else
                iw = new InformWindow(int.Parse(argsDict["-i"]));
            iw.PleaseStartVideo += StartMainWindow;
            app = new Application();
            app.Run(iw);
        }
        else
        {
            app = new Application();
            mw = new MainWindow(argsDict["-f"]);
            app.Run(mw);
        }
    }

    private void StartMainWindow(object o, EventArgs e)
    {
        mw = new MainWindow(argsDict["-f"]);
        app.MainWindow = mw;
        app.MainWindow.Show();
        iw.Close();
    }
}

The most important thing in this matter is not to get confused with the system.windows.application class

KUL
  • 391
  • 2
  • 15
0

In my case I have three windows: mainWindow, form1, form2. The mainWindow and form1 are shown. Form2 should be additionaly displayed. Form1 should get hidden. But when calling form1.Hide(); the form1 and the mainWindow get hidden. The solution in my case was:

var form2 = new Form2();
form2.Shown += (s, args) => form1.Hide(); // here only the form1 is hidden not the mainWindow
form2.Closed += (s, args) => form1.Close(); 
form2.Show();
-1

Suppose you have two Form, First Form Name is Form1 and second form name is Form2.You have to jump from Form1 to Form2 enter code here. Write code like following:

On Form1 I have one button named Button1, and on its click option write below 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();
}

Hope this code will help you

TRR
  • 1,637
  • 2
  • 26
  • 43
Shahnawaz
  • 31
  • 2
  • These four methods: `this.Visible=false; this.Hide(); this.Close(); this.Dispose();` are redundant. You need nothing more than `Close()`. Closing of a form disposes of it, setting the visibility of the form is the same as hiding it, and hiding a form is pointless when it's not going to exist before it's next paint event. – Servy Nov 16 '12 at 17:21
-2

I would solve it by doing:

private void button1_Click(object sender, EventArgs e)
{
    Form2 m = new Form2();
    m.Show();
    Form1 f = new Form1();
    this.Visible = false;
    this.Hide();
}
Servy
  • 202,030
  • 26
  • 332
  • 449
Polash
  • 1
  • 1