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.
Related
PROBLEM SOLVED
SHORT STORY
I want to detect "FormClosing()" event through different forms, ie, when form1 is closed that is instantiated within form2, can form2 detect when user presses exit in form1?
LONG STORY
My team and I are working on a windows form application. Project has two forms: one is the main form page and the other is accessed via this main form. Main form looks like this:
And the second one looks like this:
If you press "Ekle/Sil" buttons within the main form, you are directed to form 2 where you can edit database entries. When you press "Sayfayı Yenile" button in the main form, the content of the text areas are refreshed by re-fetching entries from the database.
My problem is, I want to automatically refresh the main form when the user closes the second form. My research suggests I should use an "FormClosing()" event to detect a closing form. However, I want to detect this from the main form. Instantiating main form in second form's source code doesn't seem to be a reliable solution. Anyone can tell me how to do this?
EDIT
I solved the problem:
1) Created a public method within the main form that refreshes the page.
2) Send "this" property from the main form when creating the second form.
3) Added an "FormClosed()" handler within the second form that invokes this public method.
Still, I'm looking for a better solution.
EDIT 2
Better solution InBetween's answer
Simply use the Form.Closed event of the new child windows form. Everything is handled from the main form:
void EkleSil_Clicked(object sender, EventArgs e) //or whatever method is called when button is clicked
{
var newChildForm = new ChildForm();
newChildForm.Closed += childFormClosed;
newChildForm.Show();
}
void childFormClosed(object sender, EventArgs e)
{
((Form)sender).Closed -=childFormClosed;
updateShownData();
}
You can create a event in the second form and raise it when the form is closing .
Handle the event in the main form and refresh the main form when the event is raised
Another option would be to pass Form1 as an argument to Form2. Then use the Form.Closing event in Form2 and use the Form1 reference to trigger something.
Form1 form1Ref;
public Form2(Form1 mainform)
{
form1Ref = mainform;
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
form1Ref.SomeMethod();
}
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
}
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?
In my C# application, I have the following method that is called when the main form closes.
private void FormMain_Closing(object sender, FormClosingEventArgs e)
{
// Show this dialog when the user tries to close the main form
Form testForm = new FormTest();
testForm.StartPosition = FormStartPosition.CenterParent;
testForm.ShowDialog();
}
This creates a dialog window that will show when the main form is closing. However, my issue is that when the user closes testForm, the main form closes immediately after. I've tried all sorts of variants of e.Cancel = true; and such, and still cannot cancel the main form closing.
Any ideas?
Edit: it looks like I'm running into an issue using two ShowModal()'s in succession. Looking into the issue...
Edit: Used this.DialogResult = DialogResult.None; and it seems to have fixed my problem. It is apparently a known issue in WinForms when opening a modal dialog from a modal dialog.
This code works fine with me. I think there is a problem in another part of your code.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Form testForm = new FormTest();
testForm.StartPosition = FormStartPosition.CenterParent;
testForm.ShowDialog();
e.Cancel = testForm.DialogResult == DialogResult.Cancel;
}
This could to be handled by the children too from the docs:
If a form has any child or owned
forms, a FormClosing event is also
raised for each one. If any one of the
forms cancels the event, none of the
forms are closed. Therefore the
corresponding FormClosed events are
not sent to any of the forms.
I know that you mention in your question that you have tried to use 'e.Cancel = true;' However, the following code works in my environment (.NET 4.0, Visual Studio 2010, Windows 7):
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
// Show this dialog when the user tries to close the main form
Form testForm = new FormTest();
testForm.StartPosition = FormStartPosition.CenterParent;
testForm.ShowDialog();
e.Cancel = true;
}
If this doesn't work in your case you may have other event handlers at work. In that case try this code in a newly generated Windows Forms Application.
I have a problem with modality of the forms under C#.NET. Let's say I have main form #0 (see the image below). This form represents main application form, where user can perform various operations. However, from time to time, there is a need to open additional non-modal form to perform additional main application functionality supporting tasks. Let's say this is form #1 in the image. On this #1 form there might be opened few additional modal forms on top of each other (#2 form in the image), and at the end, there is a progress dialog showing a long operation progress and status, which might take from few minutes up to few hours. The problem is that the main form #0 is not responsive until you close all modal forms (#2 in the image). I need that the main form #0 would be operational in this situation. However, if you open a non-modal form in form #2, you can operate with both modal #2 form and newly created non modal form. I need the same behavior between the main form #0 and form #1 with all its child forms. Is it possible? Or am I doing something wrong? Maybe there is some kind of workaround, I really would not like to change all ShowDialog calls to Show...
Image http://img225.imageshack.us/img225/1075/modalnonmodalproblem.png
Modal forms do exactly what "modal" means, they disable all other windows in the app. That's rather important, your program is in a somewhat perilous state. You've got a chunk of code that is waiting for the dialog to close. Really Bad Things could happen if those other windows were not disabled. Like the user could start the modal dialog again, now your code is nested twice. Or she could close the owner window of the dialog, now it suddenly disappears.
These are the exact kind of problems you'd run into if you call Application.DoEvents() inside a loop. Which is one way to get a form to behave modal without disabling other windows. For example:
Form2 mDialog;
private void button1_Click(object sender, EventArgs e) {
mDialog = new Form2();
mDialog.FormClosed += (o, ea) => mDialog = null;
mDialog.Show(this);
while (mDialog != null) Application.DoEvents();
}
This is dangerous.
It is certainly best to use modal forms the way they were designed to stay out of trouble. If you don't want a modal form then simply don't make it modal, use the Show() method. Subscribe to its FormClosing event to know that it is about to close:
private void button1_Click(object sender, EventArgs e) {
var frm = new Form2();
frm.FormClosing += new FormClosingEventHandler(frm_FormClosing);
frm.Show();
}
void frm_FormClosing(object sender, FormClosingEventArgs e) {
var frm = sender as Form2;
// Do something with <frm>
//...
}
The first thing that comes to mind would be something like this. You could disable form 1 when you launch form 2 and then have form 1 handle the closed event of the second form to re-enable itself. You would NOT open modal 2 using show dialog.
Now keep in mind, from a user perspective this is going to be quite cumbersome, you might look at doing a MDI application to get all windows inside of a single container.
Your main form will not be responsive until any modal dialogs that are in the same process space are closed. There is not work around for that.
It looks to me like you could use an MDI application setting the Form #0 IsMdiContainer property to true.
Then, you could do something alike:
public partial class Form0 {
public Form0 {
InitializeComponent();
this.IsMdiContainer = true; // This will allow the Form #0 to be responsive while other forms are opened.
}
private void button1_Click(object sender, EventArgs e) {
Form1 newForm1 = new Form1();
newForm1.Parent = this;
newForm1.Show();
}
}
Using the ShowDialog() as you stated in your question will make all of the forms Modal = true.
By definition, a modal form is:
When a form is displayed modally, no input (keyboard or mouse click) can occur except to objects on the modal form. The program must hide or close a modal form (usually in response to some user action) before input to another form can occur. Forms that are displayed modally are typically used as dialog boxes in an application.
You can use this property [(Modal)] to determine whether a form that you have obtained from a method or property has been displayed modally.
So, a modal form shall be used only when you require immediate assistance/interaction from the user. Using modal forms otherwise makes believe that you're perhaps running into a wrong direction.
If you do not want your main form to be an MDI container, then perhaps using multithreading is one solution through a simple BackgroundWorker class is the key to what you want to achieve. Thus, it looks to me like a design smell...
What is it you want to do, apart of making your main form responsive, etc.
What is it you have to do?
Explaining what you have to do, we might be able to guide you altogether into the right, or at least perhaps better, direction.
Actually the answer is very simple. Try
newForm.showDialog();
This will open a new form, while the parent one is inaccessible.