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?
Related
I'm trying to switch Windows forms after successful login at the login form, I move to the main form. The problem is once the user logs in by clicking the login button, the main form opens but the login forms stays in the background, won't go away. I tried this.hide() and this.close, but they don't work. Here's some of the code from the btnLogin event...
//connection to access database and checking if the user exist, ...
...
if (!rdr.Read())
{
MessageBox.Show("Wrong username or password.");
}
else
GlobalClass.GlobalVar = true;
GlobalClass.GlobalStr = rdr["user"].ToString();
MainScreen _main = new MainScreen();
_main.ShowDialog();
rdr.Close();
conn.Close();
this.Close();
}
you are using ShowDialog use Show method instead, here:
_main.Show();
When you use ShowDialog your program waits until you close your MainForm and doesn't go to the next line.So your second form doesn't close until you close the MainForm.
It's probably better to create and display the main form from Program.cs, and then show and dispose the LoginDialog from the OnLoad handler of the main form.
In particular if LoginDialog is created from Application.Run then closing it will exit the app, so not very useful that way around.
You can hide() then close() but you have to use an event in doing so and like others suggest I will use Show() method instead of ShowDialog().
I would probably declare globally the Main form first.
MainScreen _main;
Then when you are about to show the Main after login use event to Hide() the login Form and then an event to Close() login form once Main form is closed.
GlobalClass.GlobalVar = true;
GlobalClass.GlobalStr = rdr["user"].ToString();
_main = new MainScreen();
_main.Load += new EventHanlder(_main_Load);
_main.FormClosed += new FormClosedEventHandler(_main_FormClosed);
_main.Show();
Catch the event for Main Form loading to Hide the Login form, like:
private void _main_Load(object sender, EventArgs e)
{
this.Hide(); // Hides Login but it is till in Memory
}
Catch the event for Main Form closing to Close the Login form, like:
private void _main_FormClosed(object sender, FormClosedEventArgs e)
{
this.Close(); // Closes Login and remove this time from Memory
}
On the form called "Dev" I have the following OnFormClosing function to make sure a thread is closed properly when a user closes the form.
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
dev.stopMultipleColorsWatcher();
}
Works fine if I close the "Dev" form directly. But if the "Dev" form closes because the main form ("Form1") was closed (which causes the program to exit) the OnFormClosing() function in "Dev" is never called, so the thread keeps on running and the program' process needs to be killed via task manager.
How do I fix this? I realise I could add an OnFormClosing() function to "Form1" which then calls the OnFormClosing() function in "Dev", but I was hoping for something a bit more clean.
Update:
Dev form is opened from the main form:
private void btn_opendev_Click(object sender, EventArgs e)
{
Dev frm = new Dev();
frm.Show();
}
The main form is really called "programname.UI.Main" (I know right..) and it is opened in "Program.cs" (so the program's entry point):
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new programname.UI.Main());
}
Instead of
Dev frm = new Dev();
frm.Show();
try this
Dev frm = new Dev();
frm.Show(this);
This method shows an owner to a child form, and all events that go to the main form should go to the child forms.
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.
Hey guys i am new to the Windows application.
I have a form on which Login button click event i have shown to other Forms. Example like i have a login page after user authentication other two Forms shown. But i want after authentication of user Login Form should be close, But others two remain open.
Following is code, my Login Form name is LogIn.cs
private void btnLogIn_Click(object sender, EventArgs e)
{
if(ValidateUser())
{
//Form1
DetailForm form = new DetailForm(txtUserName.Text.ToString());
form.Show();
//Form2
Progressbar progress = new Progressbar();
progress.Show();
}
}
please write some code
You can close the form using Form.Close()
private void btnLogIn_Click(object sender, EventArgs e)
{
if(ValidateUser())
{
//Form1
DetailForm form = new DetailForm(txtUserName.Text.ToString());
form.Show();
//Form2
Progressbar progress = new Progressbar();
progress.Show();
this.Close();
}
}
There is a "Close" method on every form you can use.
The problem is that the Main message loop of your application is in the LogIn form, it means that if you stop this message loop, your application stops.
Personally I won't let the LogIn form own the main message loop of your app. I wouldn't open the DetailForm and the ProgressBar from the LogIn form, it doesn't make much sense. I'd make some parent class which controls all of them.
If you do want the LogIn form to be the main of your app but hide it once the user logs in, you could either use Hide(), or run the two child windows in seperate Threads or Processes (not Highly recommended).
Yeah was about to say tat and just noticed ur last comment! the form which is having the ValidateUser is ur LoginForm.. ur question is not very clear. So it cant be closed. you should hide it if you dont want it in the background.
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.