How to exit a Windows Forms/C# program - c#

Class A has a Form1 (subclass of System.Windows.Forms.Form) member.
class A {
Form1 form;
public A()
{
form = new Form1();
form.Show();
}
}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
A a = new A();
Application.Run();
}
The problem is I do not know how to exit the program. I have tried Application.Exit() when handling the Form.Closed event or call A.Dispose(), but the Windows Task Manager still lists the process of my program.
How do I finish this program?

Application.Run has 3 overloads. You are using this one with no arguments.
Windows runs your program in a message loop, but it doesn't care about your form.
So if you close your form it doesn't matter; the program will still run.
The second overload is what everyone uses, Application.Run(Form). This one runs a Windows message loop over your form, so when you click close on the window, the application closes.
Your code should be:
class A {
Form1 form;
public A()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
form = new Form1();
form.Show();
Application.Run(form);
}
}
[STAThread]
static void Main()
{
A a = new A();
}

Following Microsoft you should use this:
Application.Run(a.Form);
Because MSDN states that
Most Windows Forms developers will not need to use this version of the method. You should use the Run(Form) overload to start an application with a main form, so that the application terminates when the main form is closed.

I think you have a mixup there. Check the documentation for Application.Exit.
There you will see that Exit will raise the Closed event for you, and calling Exit there might cause an infinite loop (which might be causing your problem, that the application is still visible).

Try this:
Environment.Exit(1);

Related

Visual studio does not show UI while running app

I have been working on c# for about 3 hours and Visual Studio does not show the UI while running the application. It shows the UI in designer but after compiling and running, it just goes blank.
Two things to test:
In the code file Program.cs, you will find something like this:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
Does the name of the form in the line Application.Run match the name of your form?
Your form's code behind (Form1.cs) should have a constructor looking like this
public Form1() // Where the name of the constructor must match the one of the form class.
{
InitializeComponent();
// Your code goes here (if any) ...
}
Does it have this constructor? If yes, does it call InitializeComponent?
InitializeComponent is very important, because it creates the controls and configures the form. You may have replaced it with your own code. Always call it before your initialization code.
I guess the entry point if your application is wrong. Check the solution properties (right click on your application/solution in the solution explorer -> properties ) for the correct entry point.
It looks like you have more than one form.
Go to the Program.cs file and verify if the class of the form is in Application.Run() method
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main ()
{
Application.EnableVisualStyles ();
Application.SetCompatibleTextRenderingDefault (false);
Application.Run (new urltetx());
}
}

How to show multiple forms simultaneously

I know this may have been answered, but I just can't find a suitable answer. Any idea how to show more than one Windows Form?
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Main());
Application.Run(new MenuModule());
}
By declaring two Application.Run, the the Windows Form will show after I exit the first.
When you use that overload of Application.Run it will block until the form you passed has closed.
You could try:
new Main().Show();
new MenuModule().Show();
Application.Run();
This will run until you call Application.Exit even if both forms have been closed. So a better option might be:
new MenuModule().Show();
Application.Run( new Main() );
Which will cause the application to exit after the Main form has closed, regardless of the status of the MenuModule form.
As an option you could also have the Main form show the second one, that'll work too.
you can create an object in 'Main' class (form) contractor.
public main(){
.
.
.
new MenuModule().show();
.
.
.
}

Methods this.hide() vs this.close()

My c# windows forms application has 5 forms which I am displaying one after the another. When the user clicks on next button, the code I have given is:
new Form1().Show();
this.Hide();
However I do not want my current Form to hide. I want to close it/dispose it so that it does not consume memory. I want to release its resources like the images and variable used as soon as I am done with it.
For that I tried implementing:
new Form1().Show();
this.Close(); //Form 2
but this simply closes both the forms.
I even tried swapping the positions of the above two lines:
this.Close();
new Form1().Show();
but this also does same thing.
How do I release the resources of one form as soon as I am done with it? because my program throws out of memory exception when I try to re-open my Form 2 using:
new Form2().Show();
this.Hide();
You can start your NewForm in a new thread and create a new message loop
When the main message loop is closed, the application exits. In Windows Forms, this loop is closed when the Exit method is called
For more information see here.
var th = new Thread(() => Application.Run(new NewForm()));
th.SetApartmentState(ApartmentState.STA); // Deprecation Fix
th.Start();
this.Close();
Another way to do it, is to manage the application context yourself. Here is a small demo:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
using (var myApplicationContext = new MyApplicationContext(new Form1()))
{
Application.Run(myApplicationContext);
}
}
You can define your tailored made ApplicationContext in the following way:
public class MyApplicationContext : ApplicationContext
{
public MyApplicationContext(Form mainForm)
:base(mainForm)
{
}
protected override void OnMainFormClosed(object sender, EventArgs e)
{
if (Form.ActiveForm != null)
{
this.MainForm = Form.ActiveForm;
}
else
{
base.OnMainFormClosed(sender, e);
}
}
}
And now, you could do the following on the Button.Click event handler:
var f = new Form();
f.Show();
this.Close();
And the application will keep on running. Basically this way you keep the app alive while there is at least one active form.
NOTE Haven't tested it but it should work.
Closing the form which the Program start in its main function will close the application, an idea is to have a parent Form and make it the main form, and never close it, this can be a hidden form if you want.
I am not working with Windows forms since long time ago but found on this page the reason behind behavior you are getting:
http://msdn.microsoft.com/en-us/library/ms157902(v=vs.110).aspx
Typically, the main function of an application calls this method and
passes to it the main window of the application. This method adds an
event handler to the mainForm parameter for the Closed event. The
event handler calls ExitThread to clean up the application.
Also on this question How do I prevent the app from terminating when I close the startup form? there was a discussion about something the same
I am not sure if it would work for you. But when I had the same problem while dealing with a login form... i just used ShowDialog() instead of Show() , (and for me it solved the problem ) Just Like:
this.Hide();
MainForm MForm = new MainForm();
MForm.ShowDialog();
this.Close();
By default, a C# Forms application creates a "root" form in the Program.Main() method and passes that to the Application.Run() method. When this Form is closed, your program will exit.
However, you can change this behavior by using a different Application.Run() overload. Just don't pass the Form instance to Run(). Instead, show the form before calling Application.Run(), and then later on (when you finally do want the program to quit) use the Application.ExitThread() method to tell the Application class you're ready to close the application.

What is the entering method of a multi form project?

I'm working with a C# project using System.Windows.Form to create the GUI, I have two forms within the VS project( MainForm and InitialPrompt). I've never used Forms before and Google hasn't been of much help.
Intended action:
InitialPrompt Load
Click Button on InitialPrompt
Load MainForm
However, since MainForm was created first there is some property/method that allows it to load first and the InitialPrompt does not load at all. How to I make MainForm the secondary form and InitialPrompt the primary?
Thanks in advance.
namespace WindowsFormsApplication1
{
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());
}
}
}
You can change the above code to read
Application.Run(new Form2()); // or whatever the name of the second form is.
This is found in your Program.cs file.
Look for the Program.cs file inside your project. Inside you will see something like this:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
Just change new MainForm() to new InitialPrompt(). This will make InitialPrompt the main form.
Like any other .Net project it is the static void Main() method in a class defined in your project. Because of this, only one static void Main() method is allowed in a project.
NOTE: this static Main method must be defined as void return type, and it can either take no arguments, or it can be defined to take an array of strings to be passed as command line arguments.

Run multiple UI Threads

Skip to the bottom for the question; this is just some extra info
I am using a component (GeckoFX) to render some websites, well fine, yet it can only be used in a Windows Form; as it has to bind to a WinForms object that can be drawn. Because all the WinForms are running in the same thread, I can only use one GeckoFX instance at a time; so I decided to create a 'worker class' in the form of a WinForm, and add all the logic in there. The form doesn't require to communicate with the main form.
Now I can fire up 10 windows, and they will eventually work, but every new form will wait before all the other forms have handled all their GeckoFX events, as you cannot use multiple instances on one thread. Furthermore, the browser has to be on a UIThread. So:
Is it possible to create multiple UI Threads (one for each form)?
I have seen someone doing it ([edit: removed 'bad' link]), yet no one ever got his code samples working. The guy who got it working originally used some form of custom message pumping to do this kind of things, but I have no clue how to achieve something like that.
I don't think that what you ask is really what you want but creating a message pump per thread is easy, you just have to call Application.Run once per thread.
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Thread t1 = new Thread(Main_);
Thread t2 = new Thread(Main_);
t1.Start();
t2.Start();
t1.Join();
t2.Join();
}
static void Main_()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
Use Application.DoEvent().
or
Create multiply threading forms:
Thread form2Thread;
Form2 form2;
private void Form1_Load(object sender, EventArgs e)
{
form2Thread = new Thread(RunForm2);
form2Thread.SetApartmentState(ApartmentState.STA);
form2Thread.Name = "Form2 Thread"; // looks nice in Output window
form2Thread.Start();
}
public void RunForm2()
{
form2 = new Form2();
Application.Run(form2);
}
GeckoFx doesn't require a form.
GeckoWebBrowser wb = new GeckoWebBrowser();
wb.CreateControl(); //<-- the magic lays here!
wb.DocumentCompleted += delegate{ MessageBox.Show(wb.DocumentTitle); };
wb.Navigate("http://mysite.com");
Seems like it is possible.
I took backgrounder, opened TestApp, and created a new Form1 on thread/message pump #2:
private void button2_Click(object sender, EventArgs e) {
helper.Background(() => {
Form1 form2 = new Form1();
form2.Show();
});
}
The second window responds to mouse clicks etc.
Haven't actually verified if everything looks right, the freebie Visual Studio Express Edition I'm using is missing the "Threads" debug window, ahem. So I'm a bit in the dark. It seems to work, though. Let me know :-).

Categories

Resources