If I close one of my forms, they all close - c#

I am new to win forms (C#). The current form that I'm making has the option to create a new (blank) instance of itself, but if I ever close that first instance, all the others close as well. This is not what I want to happen. (Closing any form opened up from the first doesn't close any others, though)
I was thinking it may be because I am creating a new copy from within one of the copies/objects, so it is tied to that first object so it closes when it does; however, if I open up another form from the one opened from the first one and then close that one that was opened from the first one, the one that I opened up from it doesn't close.
I want it so that I can still close that first form without the others closing, and that when the last one closes, the program stops running.
Is there any way to do this?

You can run as many forms as you need but each in the separate thread
using System;
using System.Threading;
using System.Windows.Forms;
public partial class MyForm: Form
{
public MyForm()
{
InitializeComponent();
}
private void Button1Click(object sender, EventArgs e)
{
var t = new Thread(() => Application.Run(new MyForm()));
t.Start();
}
}

You should not have to close the Entry Point (MainForm) Form. Check the Main() method code in Program.cs code file.
public static void Main(string[] args)
{
// Starts the application.
Application.Run(new Form1());
}
Read this page.
To prevent a form from closing, handle the Closing event and set the
Cancel property of the CancelEventArgs passed to your event handler to
true.

You dont need to create new thread for every form. Just use this:
Form newForm1 = new Form();
this.Hide();
newForm1.ShowDialog();
this.Close();

Shortly:
The first form of every windows application is the main form.
If it closes, so does the application.
(See Program.cs for more details)
To solve this you can call Application.Run (While I don't know if it's smart or not)

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());
new Form1().Show(); // any entry point with form
Application.Run(); // without main form
}
}
Program.cs
You can use like this code block.
But when any form closed, application not finished.
(Even if the last a form in application.)
Because application not included mainform.
If application has not any a opened form.
Application will suspend in process. You can see then the task manager.
As a result you will call manually Application.Exit() method in each form close events.

Related

First form not closing, second not opening

I'd like to have a welcoming form, named the StartForm. This closes, then opens my MenuForm.
Current problem is: First one stays open, doesn't close to show the second one.
I tried several things, like simply showing and hiding them. I now try Application.run and then hide it. Unfortunately it stays open. And doesnt Application.run the second form.
static void Main()
{
Form StartForm = new Main();
MForm MenuForm = new MForm();
Application.Run(StartForm);
//
Task.Delay(500).ContinueWith((t) =>
{
StartForm.Hide();
Application.Run(MenuForm);
});
}
I expected this to Close the first form after waiting the delay, but it stays open.
Calling Application.Run() causes a new application message loop to begin running on the current thread. If a subsequent call to Application.Run() is made while the first application is running an InvalidOperationException is thrown according to the docs. However, this is not actually possible in your case as your call to Application.Run() is being invoked on the UI thread, which blocks the execution of any following code until it exits.
Instead, what we need is to bootstrap the application by using Application.Run(new Main()) and then inside of the Main form we will handle the displaying and hiding behaviour.
Here is how I would suggest achieving this:
Firstly, in your Main method, replace everything with Application.Run(new Main());.
Then inside of your Main form create a method like the following:
private void Main_Shown(Object sender, EventArgs e)
{
Task.WaitAll(Task.Delay(500));
this.Hide();
var menuForm = new MForm();
menuForm.Closed += (obj, args) => { this.Show(); };
menuForm.Show();
}
And lastly, go into your Main.Designer.cs file and make sure you subscribe the Shown event to Main_Shown method you just created in the InitializeComponent method like so:
this.Shown += new System.EventHandler(this.Main_Shown);
Explanation of what is going on here:
According to the docs the Form.Shown Event gets fired the first time a form is shown to the user. This is perfect for this use case, so we 'hook' into it and respond to it by awaiting a delay of 500 milliseconds.
Afterwards we hide the current (Main) form, create the new (MForm) form and show it. But the more important detail is that we subscribe to that form's Closed event so that when it is closed by the user, the Main form shows itself again.
use timer to Open Second form in Firstform
and Hide Firstform after show Secondform.
like this.
Main
static void Main()
{
Form StartForm = new Main();
Application.Run(StartForm);
}
FirstForm
set timer with interval 5000 and Enable it.
private void timer1_Tick(object sender, EventArgs e)
{
MForm MenuForm = new MForm();
this.Hide();
MenuForm.Show();
timer1.Stop();
}

Closing Parent without closing child

I have a project where a setup dialog (Parent) pops. When the user hit continue a main dialog is opened (Child).
From within the main dialog the user can re-edit the setup dialog (Parent). When the user clicks on X to close the setup dialog, the application terminates.
I assume this is because we close the Parent and it disposes all its children
Is it possible to close the Parent (or hide it) without closing the main dialog (child)?
If not would the following fix would work?
Open the Main Dialog as Parent and make it open the setup dialog (Child)
In the Program.cs file, you probably have a function like this:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
This function is the entry point for your application. The Application.Run() function runs the main loop of the application. The main loop of a graphical application is the place where the event handler triggers the events, the UI gets updated and so on. If an event (for example pressing a button) takes too long to process, the UI hangs. To prevent this from happening, one can use threading.
The Application.Run() function is overloaded, so if the function has a parameter (new Form1() in this case), the form becomes the 'main' form, so the main loop will exit when the form is closed.
To fix this issue, you need to remove the parameter, which will make the main loop run without closing when the form closes:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run();
}
However, this creates 2 problems:
No form is displayed at start-up, because we removed that from the Main function. To fix this, you need to create a new form in the main function, and show it:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 form = new Form1();
form.Show();
Application.Run();
}
The application will not exit when you close the form. If you close all forms, the process will be still running, so you need to call Application.Exit(); when you want the application to exit (e.g. form closing event).
Or, you just cannot understand that a modal window cannot live without a parent. When the parent is minimized, all the modal forms became hidden. When the parent is closed, the same is happening to the modal forms.
So it is a bad practice to trick the model form to stay alive after the parent dies. Just try to stay the pattern in which your second form is just another same equal form as the first one.

C# Opening a new form and closing the other one

In my program I show a login form before the main form, once the program detects a successful login I use this:
MainForm Main = new MainForm();
Main.Show();
this.Hide();
This works fine but there is a problem, the login form is still open even though it is hidden so when the program is closed the process still hangs, how can I stop this from happening?
Sorry, forgot to add, using this.Close(); doesn't work and will completely close the program.
Try something more like this:
this.Hide();
Main.ShowDialog();
this.Close();
You want to hide the login form before you show the dialog, then close the login form after the dialog has been closed.
Simply closing the Login dialog will ultimately end the application, so that's not a real solution, but you still want to hide the login.
Simply put, put things in the order you want them to go in, especially when dealing with message loops.
First, you hide the login form.
Next, you show the Main form dialog, but prevent the caller of "ShowDialog()" from continuing until the dialog is closed.
Last, once the dialog is closed, you close the login form, ending the application.
You need to specify your MainForm when you staring application and in the Load event handler of this form ask for login. In this case you will have runned application and Login for on the starting:
Program.cs
Application.Run(new MainForm());
MainForm.cs
private void Form1_Load(object sender, EventArgs e)
{
LoginForm loginForm = new LoginForm();
if (loginForm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
// check login here
}
}
P.S. Close will close your application completelly if it's main form of your application.
Change the main form to be MainForm, and when the application launches, in your MainForm_Load launch login form as a dialogbox, so they cannot access the main form.
If you need to be able to close the application from the login form, use Application.Exit(0);
If you don't want them to see the main form lookup and override SetVisibilityCore and call it inside MainForm_Load.
You can use ApplicationContext.MainForm to specify current main form for the application:
static class Program
{
public static ApplicationContext Context { get; set; }
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Context = new ApplicationContext(new LoginForm());
// pass Context instead of just new LoginForm()
Application.Run(Context);
}
}
then in in login handler:
private void login_Click(object sender, EventArgs e)
{
Program.Context.MainForm = new MainForm();
// close login form
this.Close();
// set up context to track main form instead of login
Program.Context.MainForm.Show();
}
How about this.Close() instead?

Windows forms spinning in c#

I have two windows forms.Now I have to close first one and show the second form and vice-versa.How can i do it.I was passing this pointer to the constructor of second form and then trying to
close it,but this did not work.I can not use showdialog here.
Add static variables to each form in the Program class:
static class Program
{
public static Form1 f1=null;
public static Form2 f2 = null;
public static FullClose=false;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
f1=new Form1();
f2 = new Form2();
Application.Run(f1);
}
}
Then in the Form_Closing event of each form:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (Program.FullClose==false)
{
e.Cancel = true;
this.Visible = false;
Program.f2.Show();
}
}
(Change Program.f2.Show() to Program.f1.Show() in Form2).
Of course this will stop the application from ever closing, so you should provide an extra button (or similar) that sets a boolean static variable (FullClose) that the Form_Closing events can check to see if they should properly close or not.
You must set in your application, the close is not then main form was closed, then if all forms all closed.
You must pass the pointer of the main form to second form and main form must have second form pointer.
Then implement in your forms OnClosing event, then in her implementation open other form if this success return, else set Cancel to true and return.
In every case there is one form, which represents the live of your application. This form will be started within your Program.cs file by calling
Application.Run(new MyForm());
If you try to start within this form another one and this will afterwards kill his creator, this will always lead to some bad designs.
Instead you should create some super-form. It is invisible and contains the glue code between those two forms. Right after startup it creates both forms and shows the first one. Also it registers to an (self-written) event in both forms which claims to show the other one. If your invisible form gets the event from one form it just makes the sender invisible and shows up the other one.
Last but not least you need in both (or at least in one) forms a second event, which will close the super form thous closing the application.

Very strange bug when using Show Dialog on C# Winform

I have created 2 forms in VS Studio 2008 Express Edition and declare them with public static in main program.cs file
I just want to switch between the two forms with ShowDialog and Close but when trying to close the second form and open the first form again with showdialog it says I cannot use showDialog when the form is already visible, whereas it isn't true since I closed it before to show the second form.
It asked me to set the form visible property to false before using showdialog, so I did it
internal static void CloseSecondForm(FirstForm FirstForm)
{
FirstForm .Close();
SecondForm.Visible = false;
SecondForm.ShowDialog();
}
But then it says I cannot use ShowDialog because the form is already shown in Dialog Mode and that I must close it. So I did what it asked
internal static void CloseSecondForm(FirstForm FirstForm)
{
FirstForm .Close();
SecondForm.Visible = false;
SecondForm.Close();
SecondForm.ShowDialog();
}
But it still pretends that the form is already opened with ShowDialog !
Is this a Bug in my prog or in Winform ?
Update: this is the whole code I posted in 5th answer (I want to use showdialog and not show because I may have a 3rd form in Background that I don't want the user to access):
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 = new Form1();
Form2 = new Form2();
Form1.ShowDialog();
Application.Run();
}
// called from Form1 BUTTON
internal static void ShowForm2(Form1 Form1)
{
Form1.Hide();
Form2.ShowDialog();
}
// called from Form2 BUTTON
internal static void ShowForm1(Form2 Form2)
{
Form2.Hide();
Form1.ShowDialog();
}
I tried with Hide as suggested but it doesn't work either. This is the whole program, what I want to do is very simple: I have two forms initially created in program with one button on each form to close self and open the other. I put all the logic in program.cs below:
using System;
using System.Windows.Forms;
namespace twoforms
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
///
public static Form1 Form1;
public static Form2 Form2;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 = new Form1();
Form2 = new Form2();
Form1.ShowDialog();
Application.Run();
}
// called from Form1 BUTTON
internal static void ShowForm2(Form1 Form1)
{
Form1.Hide();
Form2.ShowDialog();
}
// called from Form2 BUTTON
internal static void ShowForm1(Form2 Form2)
{
Form2.Hide();
Form1.ShowDialog();
}
}
}
This is a bug in your program. When you have two instances of a form (call them A and B), you obviously cannot continually show one from the other using ShowDialog. If you could do this, it would mean that A shows B modally, and B then shows A modally, and A then shows B modally etc. This would be like building a house with two bricks, where you just keep taking the bottom brick and placing it on top of the other.
Your best solution is to not make these forms static, and instead just create new instances of each form as you need them. Your second-best solution is to use Show instead of ShowDialog; if you only have one of these forms showing at a time anyway, ShowDialog has no purpose.
Static forms are almost always a bad idea (and I'm being polite about "almost"). If your forms are taking a long time to create, you should identify what resource is taking so long to load and cache that as a static object, instead of trying to cache the entire form as static.
This is from MSDN:
When a form is displayed as a modal
dialog box, clicking the Close button
(the button with an X at the
upper-right corner of the form) causes
the form to be hidden and the
DialogResult property to be set to
DialogResult.Cancel. Unlike modeless
forms, the Close method is not called
by the .NET Framework when the user
clicks the close form button of a
dialog box or sets the value of the
DialogResult property. Instead the
form is hidden and can be shown again
without creating a new instance of the
dialog box. Because a form displayed
as a dialog box is not closed, you
must call the Dispose method of the
form when the form is no longer needed
by your application.
So once you show a form using ShowDialog and you now want to close it, just let it return DialogResult.Cancel
This will hide (it will still be in memory) your first form. Now you can call ShowDialog on your second form. Again, if you want to switch to first form then let the second form return DialogResult.Cancel and now just call ShowDialog on first form.
Try to use Hide() instead of Close(). I had a similar problem in the past and Hide() worked for me.
I think you should really treat Modal dialogs like method calls, and try to use the result of the Call to ShowDialog to determine what you want to do next? if you have a requirement to switch between dialogs you should use some sort of result (Maybe simply DialogResult see my example) or a public property of the dialog to determine if you need to Show another dialog, If you need to call one modal dialog from another you should think of it like a stack of forms, that effectively (even if you do make one invisible before calling another) place one upon the other. You really want to minimise this stacking of forms.
This is a bit of a contrived example but each form here simply has a single button with DialogResult set to OK.
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
bool exit = false;
while (true)
{
if (exit) break;
using (Form1 frm = new Form1())
{
switch(frm.ShowDialog())
{
case DialogResult.OK:
break;
default:
exit = true;
break;
}
}
if(exit) break;
using (Form2 frm = new Form2())
{
switch(frm.ShowDialog())
{
case DialogResult.OK:
break;
default:
exit = true;
break;
}
}
}
}
to exit simply click the red close (x) button.
Check out the difference between Close and Hide. And the difference between Show and ShowDialog.
It's not really clear to me what you want to achieve; you only (partially) describe what you done in code and the symptom of the problem you are having. Could you please describe what you are trying to do?
If your goal is to have two dialogs showing from your main window where only one of the two can be visible at the same time, then there are perhaps better solutions than using two static (=global) public Form instances that you show using ShowDialog.
Have you thought of using one dialog Form for this that just changes it appearance depending on the situation?

Categories

Resources