c# open a new form then close the current form? - c#

For example, Assume that I'm in form 1 then I want:
Open form 2( from a button in form 1)
Close form 1
Focus on form 2

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

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

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

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.

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

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

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

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

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
}

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

This code may help you:
Master frm = new Master();
this.Hide();
frm.ShowDialog();
this.Close();

this.Visible = false;
//or // will make LOgin Form invisivble
//this.Enabled = false;
// or
// this.Hide();
Form1 form1 = new Form1();
form1.ShowDialog();
this.Dispose();

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

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:
I used clean code, so I deleted App.xaml and create Program.cs
Next, a window manager was created
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

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

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

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

Related

How to switch between forms without creating new instance of forms?

in my application i have four forms form1 form2 form3 form4 .and each form have two buttons i.e next and previous buttons to switch between forms .and my question is how can i Switch between forms without creating new instance of forms? below is my code
In Form1:
public Form1()
{
InitializeComponents();
}
private void Next_Click(object sender, EventArgs e)
{
this.Hide()
Form2 form2 = new Form2();
form2.Show();
}
In Form2:
public Form2()
{
InitializeComponents();
}
private void Previous_Click(object sender, EventArgs e)
{
this.Hide();
Form1 form1 = new Form1();
form1.Show();
}
private void Next_Click(object sender, EventArgs e)
{
this.Hide();
Form3 form3 = new Form3();
form3.Show();
}
In Form3:
public Form3()
{
InitializeComponents();
}
private void Previous_Click(object sender, EventArgs e)
{
this.Hide();
Form2 form2 = new Form2();
form2.Show();
}
private void Next_Click(object sender, EventArgs e)
{
this.Hide();
Form4 form4 = new Form4();
form4.Show();
}
In Form4:
public Form4()
{
InitializeComponents();
}
private void Previous_Click(object sender, EventArgs e)
{
this.Hide();
Form3 form3 = new Form3();
form3.Show();
}
In Main:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
In above code i am creating new instances of forms every time..,How can i Avoid this and How can i Switch between forms without creating new instances of forms.... please help me
Since you are accessing your forms sequentially just make sure that you use the Show Method that assigns the owner to the created Form and assign it to a class level variable after you create it. Something like this should work for you.
Form1
public partial class Form1 : Form
{
Form2 frm2;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (frm2 == null)
{
frm2 = new Form2(); //Create form if not created
frm2.FormClosed += frm2_FormClosed; //Add eventhandler to cleanup after form closes
}
frm2.Show(this); //Show Form assigning this form as the forms owner
Hide();
}
void frm2_FormClosed(object sender, FormClosedEventArgs e)
{
frm2 = null; //If form is closed make sure reference is set to null
Show();
}
}
Form2
public partial class Form2 : Form
{
Form3 frm3;
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Owner.Show(); //Show the previous form
Hide();
}
private void button2_Click(object sender, EventArgs e)
{
if (frm3 == null)
{
frm3 = new Form3();
frm3.FormClosed += frm3_FormClosed;
}
frm3.Show(this);
Hide();
}
void frm3_FormClosed(object sender, FormClosedEventArgs e)
{
frm3 = null;
Show();
}
}
Form3
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Owner.Show();
Hide();
}
}
May be a easy solution. You can make a class that contains static object of all forms that you need. So you will be able to access all these forms from any forms of your choice and the good thing is they are initialized once.
public class formList
{
private static Form1 _form1 = new Form1();
public static Form1 form1 { get {return _form1;}
.................
............
}
Try This:
Form1 myForm =(Form1) Application.OpenForms["Form1"];
myForm.Show();
You can check if the form of interest exists, and if not create it:
public static T OpenOrCreateForm<T>()
where T: Form, new() {
T result;
// Test if form exists
foreach(Form form in Application.OpenForms) {
result = form as T;
if (!Object.ReferenceEquals(null, result)) {
// Form found; and this is the right place
// to restore form size,
// bring form to front etc.
if (result.WindowState == FormWindowState.Minimized)
result.WindowState = FormWindowState.Normal;
result.BringToFront();
return result;
}
}
// Form doesn't exist, let's create it
result = new T();
// Probably, you want to show the created form
result.Show();
resturn result;
}
...
private void Previous_Click(object sender, EventArgs e)
{
Hide();
OpenOrCreateForm<Form1>();
}
private void Next_Click(object sender, EventArgs e)
{
Hide();
OpenOrCreateForm<Form3>();
}
public bool IsFormAlreadyOpen(Type FormType)
{
foreach (Form OpenForm in Application.OpenForms)
{
if (OpenForm.GetType() == FormType)
return true;
}
return false;
}
This function can be used to find out whether a form is already opened or not
call IsFormAlreadyOpen(Form4) if it returns true which means Form4 is already opened
and in your case
in every forms constructor() create next and previous forms object
and in the button click calls IsFormAlreadyOpen() to find out whether the form is already opened or not and if it already opened just bring that form in front
other wise display the form using obj.show() method
and hide or close the parent form
Looks like you are trying to achieve wizard like feature. I would recommend having a single form. Then, add a customized tab control to it. Add buttons to form that moves previous and next.
To customize tab control, this is what you need to do:
public class CustomWizard : TabControl
{
/// <summary>
/// This method traps windows message and hides other tabs in the tab control.
/// Message trapped: TCM_ADJUSTRECT
/// </summary>
/// <param name="m">Reference to Windows message</param>
protected override void WndProc(ref Message m)
{
// Second condition is to keep tab pages visible in design mode
if (m.Msg == 0x1328 && !DesignMode)
{
m.Result = (IntPtr)1;
}
else
{
base.WndProc(ref m);
}
}
/// <summary>
/// This method traps the press to stop users from selecting tab page via keyboard
/// </summary>
/// <param name="ke">Event details</param>
protected override void OnKeyDown(KeyEventArgs ke)
{
if (ke.Control && ke.KeyCode == Keys.Tab)
return;
base.OnKeyDown(ke);
}
private void InitializeComponent()
{
this.SuspendLayout();
this.ResumeLayout(false);
}
}
This tab control will only display one tab at a time. Although, at design time you can see them all. Add this and buttons to your form. On button click, merely set the SelectedIndex property of this tab control.
I had the same issue. An application I needed that had many forms and I needed to switch between forms forward n backward without losing the data. I came up with the following solution and it worked for me.
In the main (Program.cs) file, write the following two classes:
static class Variables
{
public static DataSet Configurations = new DataSet();
public static float ExchangeRate = 0;
public static Dictionary<string, int> ItemsCategories = new Dictionary<string, int>();
public static Dictionary<string, float> WeightUnits = new Dictionary<string, float>();
}
static class Forms
{
public static Form2 F_Form2 = new Form2();
public static Form3 F_Form3 = new Form3();
}
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());
}
}
The first class is used for Global variables that can be used across the forms. You can access any variable by:
Variables.ExchangeRate = 7.2; //(for ex).
The second class is where you define new instance of all your forms. You can hide n show them anywhere across all the forms by:
Forms.F_Form3.Show();
or
Forms.F_Form2.Hide();
This works smoothly and perfect for me. Try it.
Just remove the this.hide() in the first form and the [formNameHere].show(); in the second form.
Like this:
Form 1:
public Form1()
{
InitializeComponents();
}
private void Next_Click(object sender, EventArgs e)
{
this.Hide()
Form2 form2 = new Form2();
form2.Show();
}
Form 2:
public Form2()
{
InitializeComponents();
}
private void Previous_Click(object sender, EventArgs e)
{
Form1 form1 = new Form1();
this.Hide();
}
private void Next_Click(object sender, EventArgs e)
{
Form3 form3 = new Form3();
this.Hide();
}
etc.. not good at explaining, and with C# really. But this should work.
//In Form1
private static Form1 i_Instance = null;
public static Form1 Instance
{
get
{
if (Form1.i_Instance == null) Form1.i_Instance = new Form1();
return Form1.i_Instance;
}
}
// And instantiation in other forms shall look like following
Form1 F1 = Form1.Instance;
F1.Show();

Opening a previous form when one is closed

First of all, I am a newcomer to C# and programming in general. I've searched pretty thoroughly, but I can only find instances where someone wants to open another form and hide the one that the button was pressed on.
In this instance, I'm having issues with my program continuously running when I press the (X) on any form other than the main "Form1".The form-to-form navigation works fine. i.e.: clicking a button hides the main window and opens the appropriate form, and the "back" button on that form hides itself and shows (I guess another instance) of the previous "main" form. --I could probably use some guidance in that, too. lol
I wouldn't mind if it closed the entire application if the X was pressed, but I need to have the "X" present on all windows and all windows need to exit the entire app if the X is pressed. Any suggestions?
Thanks in advance,
Code:
Form1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void btnTransaction_Click(object sender, EventArgs e)
{
Transaction transactionForm = new Transaction();
Form mainForm = this;
transactionForm.Show();
mainForm.Hide();
}
}
Transaction Form:
public partial class Transaction : Form
{
public Transaction()
{
InitializeComponent();
}
private void button4_Click(object sender, EventArgs e)
{
Form1 mainForm = new Form1(); //not sure if I'm doing this right..
this.Hide(); //I don't know how to "reuse" the original Form1
mainForm.Show();
}
}
I would recommend you create an MDI Container for this. Drag and drop a MenuStrip from the ToolBox to Form1 and then create a ToolStripMenuItem "form2" in MenuStrip.
Now you can call your form2 in form1 like this
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
IsMdiContainer = true;
}
Form2 frm2;
public void CreateMdiChild<T>(ref T t) where T : Form, new()
{
if (t == null || t.IsDisposed)
{
t = new T();
t.MdiParent = this;
t.Show();
}
else
{
if (t.WindowState == FormWindowState.Minimized)
{
t.WindowState = FormWindowState.Normal;
}
else
{
t.Activate();
}
}
}
private void form2ToolStripMenuItem_Click(object sender, EventArgs e)
{
CreateMdiChild<Form2>(ref frm2);
}
}
When by clicking ToolStripMenuItem you fire ToolStripmenuItem event , it will show Form2 as child in form1 i.e the mdi container and will be closed when you close form1.
public partial class Transaction : Form
{
Form1 _mainForm;
public Transaction(Form1 mainForm)
{
InitializeComponent();
_mainForm = mainForm;
}
private void button4_Click(object sender, EventArgs e)
{
this.Close(); //since you always create a new one in Form1
_mainForm.Show();
}
}
You can use the use Form.ShowDialog()
When this method is called, the code following (code below the 'ShowDialog()') it is not executed until after the dialog box is closed.
private void button4_Click(object sender, EventArgs e)
{
Form1 mainForm = new Form1();
this.Hide();
mainForm.ShowDialog();
this.Show();
}
You could use the ShowDialog() method that will require the user to interact with the new form before returning to the previous form. For instance you could try this:
public void btnTransaction_Click(object sender, EventArgs e)
{
using (var transactionForm = new Transaction())
{
this.Hide();
if (transactionForm.ShowDialog() == DialogResult.OK)
{
this.Show();
}
}
}
The DialogResult is something you can set on the TransactionForm like so:
private void button4_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
That's a pretty standard way of forcing interaction on a new form.
protected override void OnClosing(CancelEventArgs e)
{
this.Hide();
menu menu = new menu("administrator");
menu.ShowDialog();
this.Close();
}
//happy coding

How do I prevent the app from terminating when I close the startup form?

There is two Forms in my project : Form1 and Form2.
There is a button in Form1, and what I want to do is closing Form1 and showing Form2 when that button clicked.
First, I tried
Form2 frm = new Form2();
frm.Show();
this.Close();
but as Form1 was closed, Form2 also got closed.
Next, I tried
Form2 frm = new Form2();
frm.Show();
this.Hide();
but there is a disadvantage that the application does not exit when the Form2 is closed.So, I had to put in additional sources in form_FormClosing section of Form2.
Hmm.... I wonder whether this is the right way....So, what is the proper way of handling this problem?
The auto-generated code in Program.cs was written to terminate the application when the startup window is closed. You'll need to tweak it so it only terminates when there are no more windows left. Like this:
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var main = new Form1();
main.FormClosed += new FormClosedEventHandler(FormClosed);
main.Show();
Application.Run();
}
static void FormClosed(object sender, FormClosedEventArgs e) {
((Form)sender).FormClosed -= FormClosed;
if (Application.OpenForms.Count == 0) Application.ExitThread();
else Application.OpenForms[0].FormClosed += FormClosed;
}
By default, the first form controls the lifetime of a Windows Forms application. If you want several independent windows forms your application context should be a separate context from the forms.
public class MyContext : ApplicationContext
{
private List<Form> forms;
private static MyContext context = new MyContext();
private MyContext()
{
forms = new List<Form>();
ShowForm1();
}
public static void ShowForm1()
{
Form form1 = new Form1();
context.AddForm(form1);
form1.Show();
}
private void AddForm(Form f)
{
f.Closed += FormClosed;
forms.Add(f);
}
private void FormClosed(object sender, EventArgs e)
{
Form f = sender as Form;
if (form != null)
forms.Remove(f);
if (forms.Count == 0)
Application.Exit();
}
}
To use the context, pass it to Application.Run (instead of the form). If you want to create another Form1, call MyContext.ShowForm1() etc.
public class Program
{
public void Main()
{
Application.Run(new MyContext());
}
}
You can take this way:
form2 f2=new form2()
this.Hide();
f2.Show();
Hope it was helpful.
Write that into your method which is executed while FormClosing event occure.
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
// Display a MsgBox asking the user if he is sure to close
if(MessageBox.Show("Are you sure you want to close?", "My Application", MessageBoxButtons.YesNo)
== DialogResult.Yes)
{
// Cancel the Closing event from closing the form.
e.Cancel = false;
// e.Cancel = true would close the window
}
}

WinForm New instance of form

I have this block of code:
Form1 newForm = new Form1();
newForm.Show();
//The rest of this code has been omitted
more or less. Form1 is just for example purposes. My issue is that I am creating a text editor (continuation of my last question, basically) and I want to be able to have more than one copy of Form1 open at once.
This code allows me to do that, which is great, but I want to be able to close the old one and still have the newForm on the screen. Currently, if I close Form1, I say goodbye to newForm.
Is this possible? I don't want to have to just white-out all the next like Notepad does.
I'm guessing your Form1 is also the one created and passed to Application.Run() in your main method, correct? Something like Application.Run(new Form1());
In that case (which is the default), you are telling the framework to exit the application when that form closes.
You probably want to change your main method to use the overload of Application.Run() that takes an ApplicationContext, and within the app context, create your forms - then when your last form closes, you can exit the application. The example in the link to MSDN shows a very similar case.
You could simply change main to:
Form1 newForm = new Form1();
newForm.Show();
Application.Run();
but the issue with this is that the application may not exit correctly without more housekeeping by you.
Added:
This is a simple example, but shows the concept. Create a ApplicationContext class like this one:
public class CustomContext : ApplicationContext
{
private readonly List<Form1> _openForms = new List<Form1>();
public CustomContext()
{
CreateForm();
}
private void CreateForm()
{
Form1 form = new Form1();
form.OpenNewForm += (sender, args) => CreateForm();
form.Closed += (sender, args) => FormClosed(sender as Form1);
_openForms.Add(form);
form.Show();
}
private void FormClosed(Form1 form)
{
_openForms.Remove(form);
if (_openForms.Count == 0)
{
ExitThread();
}
}
}
In your Program class, change main to Run(..) your new context class:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new CustomContext());
}
And then in your Form1, make sure you have an event, and trigger that event to open new forms (note that in "real" code I'd probably abstract this away, or most likely let my DI container handle registration, but this shows the point much clearer) :
public event EventHandler OpenNewForm;
private void ButtonClick(object sender, EventArgs e)
{
//instead of showing a new form, we just raise this event
if (OpenNewForm != null) OpenNewForm(this, EventArgs.Empty);
}
What this does, is let the ApplicationContext manage your open forms, so that closing the first one (or any of them) does not exit the application until you close the last one. Once the last form closes, it exits the app.
You could do this so many different ways. For a working example of what you want to do, in the Program.cs file change the Main method():
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new Form1());
Form1 frm = new Form1();
GlobalVariables.FormsList = new List<Form1>(); //new
GlobalVariables.FormsList.Add(frm); //new
frm.Show();
Application.Run();
}
Then on each of your Form1's have a button (or other event) that instantiates a new instance of the form1:
private void button1_Click(object sender, EventArgs e)
{
Form1 frm = new Form1();
GlobalVariables.FormsList.Add(frm); //new
frm.Show();
}
Edit: Also add the following code to the FormClosing event:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (GlobalVariables.FormsList.Count == 1)
{
Application.Exit();
}
else
{
GlobalVariables.FormsList.RemoveAt(GlobalVariables.FormsList.Count - 1);
}
}
Edit: Here is the new GlobalVariables class with the list of Forms to aid form management:
public class GlobalVariables
{
public static List<Form1> FormsList { get; set; }
}
If you are closing the form using it's 'x' button it will not affect the other form.
If you are closing by code you should get the object of that form properly and close it. It would be better if you can keep a catalog of forms so that the management will be easy.
If there are any static variables involved in between try changing that logic without static variables as they are shared across the objects.
Depending on what exactly you want to do, you can have the form launched by Application.Run be a form that just launches other forms, (e.g. your text-editor form).
Something like: (This is just an example to demonstrate the idea.)
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Shown += Form1_Shown;
}
void Form1_Shown(object sender, EventArgs e)
{
TextEditorForm frm2 = new TextEditorForm(this);
frm2.Show();
this.Hide();
}
}
And:
public partial class TextEditorForm : Form
{
Form1 frm1;
public TextEditorForm(Form1 frm1)
{
InitializeComponent();
this.frm1 = frm1;
}
private void button1_Click(object sender, EventArgs e)
{
frm1.Show();
this.Close();
}
}

controling multiple forms show, hide or close with one form in c#

I want to be able to show, hide or close some other forms within one form. the idea is my program starts with one form and there are some buttons that will show other forms. That is if user clicks on a button for bringing on another form, this main form should minimize and whenever user close the other form this form will be back to normal or maximized state.
The code looks like this for my main form that controls other forms (Form1.cs):
namespace MultipleForms
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/*
* I want to make a public reference to this Form1
* So that when user closes Form2 That is F2 this form will be
* set back to normal or maximized state
*/
private void buttonStartForm2_Click(object sender, EventArgs e)
{
//Declare Form2
Form2 F2 = new Form2();
//Show Form2
F2.Show();
//Minimize Form1
this.WindowState = FormWindowState.Minimized;
}
}
}
And this is Form2.cs
namespace MultipleForms
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
//FormClosed event handler
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
//Closing Form2
this.Close();
//Now I need a code to make Form1 to recover from minimized
// state to normal or maximized state. how do I should refer to it?
}
}
}
I think I have to do some stuff on form closing event, but how can I initilize the Form1.cs as something public? or I also should initilize Form1.cs in Form2.cs also? or maybe it should be done through Program.cs file:
namespace MultipleForms
{
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());
}
}
}
P.S: it is crtitical that Form2 should be closed, not hided
UPDATE
Using Hans solution, it is the best to use it this way:
private bool isEnabledCmpFrm = false;
public void buttonStartComparisonForm_Click(object sender, EventArgs e)
{
if (!isEnabledCmpFrm)
{
ComparisonForm CmpFrm = new ComparisonForm();
CmpFrm.Show();
CmpFrm.WindowState = FormWindowState.Normal;
this.WindowState = FormWindowState.Minimized;
isEnabledCmpFrm = true;
CmpFrm.FormClosed += delegate
{
this.WindowState = FormWindowState.Normal;
isEnabledCmpFrm = false;
};
}
}
If I understand correctly, you can hook into the Form Closing event.
So in your main form you can do something like:
Form2 form2 = new Form2();
form2.Show();
form2.FormClosing += new FormClosingEventHandler(form2_FormClosing);
void form2_FormClosing(object sender, FormClosingEventArgs e)
{
this.Show();
}
Don't have a form listen to its own events. The code needs to go in Form1. Like this:
Form2 F2 = new Form2();
F2.FormClosed += delegate { this.WindowState = FormWindowState.Normal; };
F2.Show();
this.WindowState = FormWindowState.Minimized;
You need to pass a reference to the main form to the child forms and use the main form's show method to make it visible again when the child form is closing.

Categories

Resources