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
}
}
Related
This question will definitely seem redundant but I've tried seemingly everything!
Ok I have form1 and form 2. I want to open form2 from buttonclick on form1 and have form1 close.
I've tried the:
Form2 newform = new Form2();
this.Close();
newform.Show();
I've tried moving the second line in all possible places inside the buttonclick function.
But my problem is that if I use the "this.Close();" command it closes both forms, if I use the "this.Hide();" command it leaves the process open and I have to manually close it to debug again.
The(this.Close();" works on any other form (ex. form2 close => open form3 ETC)
Does anyone know any other way to have it close it but not close the entire application?
I tried to use ApplicationContext in Program.cs.
Take a look at the below code. Form1 and Form2 both contain a Button.
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main ()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MyApplicationContext context = new MyApplicationContext();
Application.Run(context);
}
public class MyApplicationContext : ApplicationContext
{
private Form1 form1 = new Form1();
public MyApplicationContext ()
{
form1 = new Form1();
form1.Show();
}
}
}
Below is the code for Form1
private void frm1Button1_Click (object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.Show();
this.Close();
}
And here is for Form2.
private void frm2Button1_Click (object sender, EventArgs e)
{
Form1 frm1 = new Form1();
frm1.Show();
this.Close();
}
The problem you are facing is that you cannot close the main form of an application (without closing the whole app). you need to rethink how your app is organized and maybe hide the main form while the other one is on the screen or something similar.
My application launches a non-modal dialog on a button click. If user clicks on that button again, I would like to do a check if that form is already running and wonder if its possible?
You can use Application.OpenForms Property
if (Application.OpenForms.OfType<YourNonModalFormType>().Any())
// one is already opened
If you want to close this form:
var form = Application.OpenForms.OfType<YourNonModalFormType>().FirstOrDefault();
if (form != null)
{
// launched
form.Close();
}
Another approach is to manually declare a variable to track your form instance:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Form2 f2 = null;
private void button1_Click(object sender, EventArgs e)
{
if (f2 == null || f2.IsDisposed)
{
f2 = new Form2();
f2.Show();
}
else
{
f2.Close();
}
}
}
I've got two forms, with subForm being called/created by a buttonClick in Form1. Right now I can initiate subForm, hide Form1, and then unhide Form1 when subForm is closed. What I'd like to be able to do is:
If user clicks changeform button, check to see if subForm is active but hidden
If no, then initiate subForm, else hide Form1, unhide subForm and pass control to it
If user clicks subForm's changeform button, hide subForm, unhide Form1 and pass control to it
If user clicks the "X" in the upper right corner of the form, then close the application, regardless of which form is active. (Right now, selecting the "X" closes the subForm and opens/unhides Form1.)
I can find solutions that do part of the requirements (and maybe all, I'm just too noob to know). To repeat from my previous question here, the code I have so far is:
Form1
private void countClick(object sender, EventArgs e)
{
this.Hide();
subForm myNewForm = new subForm();
myNewForm.ShowDialog();
this.Show();
countSelect.Checked = false;
}
and subForm
private void totalClick(object sender, EventArgs e)
{
this.Close();
}
This works, but it's not really elegant.
I think the best way to do this is to roll your own ApplicationContext. This allows you full control over the application lifetime without having it being tied to a specific Window. See http://msdn.microsoft.com/en-us/library/ms157901.aspx for more information.
Here's an example:
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MyApplicationContext());
}
}
public class MyApplicationContext : ApplicationContext
{
public MyApplicationContext()
{
ShowForm1();
}
public void ShowForm1()
{
if (_form2 != null)
_form2.Hide();
if (_form1 == null)
{
_form1 = new Form1(this);
_form1.FormClosed += OnFormClosed;
}
_form1.Show();
MainForm = _form1;
}
public void ShowForm2()
{
if (_form1 != null)
_form1.Hide();
if (_form2 == null)
{
_form2 = new Form2(this);
_form2.FormClosed += OnFormClosed;
}
_form2.Show();
MainForm = _form2;
}
private void OnFormClosed(object sender, FormClosedEventArgs e)
{
if (_form1 != null)
{
_form1.Dispose();
_form1 = null;
}
if (_form2 != null)
{
_form2.Dispose();
_form2 = null;
}
ExitThread();
}
private Form1 _form1;
private Form2 _form2;
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public Form1(MyApplicationContext context)
: this()
{
_context = context;
}
private void button1_Click(object sender, EventArgs e)
{
if (_context != null)
_context.ShowForm2();
}
private readonly MyApplicationContext _context;
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public Form2(MyApplicationContext context)
: this()
{
_context = context;
}
private void button1_Click(object sender, EventArgs e)
{
if (_context != null)
_context.ShowForm1();
}
private readonly MyApplicationContext _context;
}
So we'll start out by going to the child form and creating a new event that can be used to notify the parent when it wants to change forms:
public event Action ChangeForm;
Then we fire the event and hide the child form when it wants to change forms:
private void ChangeForm_Click(object sender, EventArgs e)
{
Hide();
if (ChangeForm != null)
ChangeForm();
}
The parent form needs an instance of the child form as an instance field:
private subForm child = new subForm();
And it needs to initialize it in it's constructor, both adding handlers to the ChangeForm event to show the parent, and to the closed event to close itself:
public Form1()
{
InitializeComponent();
child.ChangeForm += () => Show();
child.FormClosed += (s, args) => Close();
}
Then all that's left is for the parent form to hide itself and show the child when it wants to change forms:
private void ChangeForm_Click(object sender, EventArgs e)
{
Hide();
child.Show();
}
Why not simply setting them to foreground, topmost, and so on ?
And setting them back vice versa ?
---added as comment as proposed
To access MainForm fromsubForm:
Create a constructor in your subForm and a field:
MainForm MainFormRef_Field;
subForm(MainForm MainFormRef)
{
this.MainFormRef_Field = MainFormRef;
}
Now you can access your MainForm using this reference. Like this:
MainFormRef_Field.Show();
MainFormRef_Field.Hide(); //or how ever you want to handle it
To access subForm fromMainForm:
To handle your subForm use the object you created for it. Here:
subForm myNewForm = new subForm();
To close whole application if any of the form closes:
Set a Form_Closing event for both forms:
private void MainForm_Closing(object sender, EventArgs e)
{
Application.Exit();
}
private void subForm_Closing(object sender, EventArgs e)
{
Application.Exit();
}
Note:
I am not writing the whole code for all of your cases. Set the variables, check the conditions. Its all up to you that how code it. All the main points you needed I've provided you the solution of them.
i have 2 forms, those are form1.cs and form2.cs
on the form1, it has button1, which will call form2 to show
here's the button1 code
private void button1_Click(Object sender, EventArgs e )
{
form2 form = new form2();
form2.show(); // to call form2
this.dispose(); //to dispose form1
}
and then form2 showed, and it closed suddenly. anyone know how to solve this ?
When you close your main form with this.dispose() you are terminating the program causing form2 to be disposed also because you are diposing the reference to form2. You would be better off passing a reference to your form1 to form2 and using this.Hide() instead.
You can try something like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 form = new Form2();
form.setParent(this);
form.Show();
this.Hide();
}
}
And in form2 to go back to form1
public partial class Form2 : Form
{
Form parentForm;
public Form2()
{
InitializeComponent();
}
public void setParent(Form value)
{
parentForm = value;
}
private void button1_Click(object sender, EventArgs e)
{
parentForm.Show();
this.Close();
}
}
private void button1_Click(Object sender, EventArgs e )
{
form2 form = new form2();
form2.show(); // to call form2
this.hide(); //to hide form1
}
if form1 is program starter then application will close . Hence instead
this.dispose();
U just write
this.hide();
Show() does not wait for form2 to close before continuing to the next command (dispose).
This will end up in closing form2 because it's probably running on a background thread.
Use ShowDialog to hold the execution of Dispose until the second form closes.
Also, you can set the second form to run on a foreground thread. This way the second form will not be dependent on the life of the first.
You can either use this.Hide() which should hide your current form or use a thread to open the new form.
Example: C# open a new form, and close a form...
So I want basically the user to login in first in order to use the other form. However, my dilemma is that the login box is in Form2, and the main form is Form1.
if ((struseremail.Equals(username)) && (strpasswd.Equals(password)))
{
MessageBox.Show("Logged in");
form1.Visible = true;
form1.WindowState = FormWindowState.Maximized;
}
else
{
MessageBox.Show("Wow, how did you screw this one up?");
}
However, Form1 doesn't become visible, (since I launch it as visble = false) after they log in. Can someone help?
EDIT:
Brilliant response, but my problem is still here. I basically want to load Form2 First, (which is easy I run Form1 and set it to hide) But when Form2 is closed, I want Form1 to be closed as well.
private void Form2_FormClosing(Object sender, FormClosingEventArgs e)
{
Form1 form1 = new Form1();
form1.Close();
MessageBox.Show("Closing");
}
this doesn't seem to work...
You will need to pass the reference of one form to another, so that it can be used in the other form. Here I've given an example of how two different forms can communicate with each other. This example modifies the text of a Label in one form from another form.
Download Link for Sample Project
//Your Form1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2(this);
frm.Show();
}
public string LabelText
{
get { return Lbl.Text; }
set { Lbl.Text = value; }
}
}
//Your Form2
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private Form1 mainForm = null;
public Form2(Form callingForm)
{
mainForm = callingForm as Form1;
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
this.mainForm.LabelText = txtMessage.Text;
}
//Added later, closing Form1 when Form2 is closed.
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
mainForm.Close();
}
}
(source: ruchitsurati.net)
(source: ruchitsurati.net)
When you log in and do Form1.visible = true; have you also tried Form1.Show(); that should show form2
However, Personally, I would prefer setting the application to run form2 directly in the program.cs file.
static void Main()
{
Application.Run(new Form2());
}
then when user successfully logs in, do
form1.Show();
this.Hide(); // this part is up to you
mind you, in form2, when / after you instantiate form1, you might want to also add this :
newform1.FormClosed += delegate(System.Object o, FormClosedEventArgs earg)
{ this.Close(); };
this closes form2 when form1 is closed
better yet do form1.Show() in a new thread, and then this.Close(); for form2. this removes the need of adding to the form2's FormClosed event: you can thus close form2 immediately after starting form1 in a new thread. But working with threads might get a little complicated.
EDIT:
form2 is form1's parent. if form2 is your main application form, closing it closes your program (generally). Thus you either want to just hide and disable form2, and close it only after form1 is closed, or start form1 in a new thread. Your edit pretty much opens form1, then immediately closes it.