I have Forms (Admin, login, user). There is no error when accessing user form, it is simply opening it without user and pass.
The error I encountered is when I login and Admin form is present, when I click in my toolstripbutton the whole application exits.
This is the method I applied in every toolstripbutton:
public void CloseAllActiveForms()
{
List<Form> openForms = new List<Form>();
foreach (Form f in Application.OpenForms)
openForms.Add(f);
foreach (Form f in openForms)
{
if (f.Name != "FrmAdmin")
{
f.Close();
}
}
}
And this is the code in every toolstipbutton:
private void toolStripButton4_Click(object sender, EventArgs e)
{
CloseAllActiveForms();
FrmDashboard objFORM = new FrmDashboard();
objFORM.MdiParent = this;
objFORM.TopLevel = false;
objFORM.FormBorderStyle = FormBorderStyle.None;
objFORM.Dock = DockStyle.Fill;
pnlMain.Controls.Add(objFORM);
objFORM.Show();
}
This is design sample.
Every click in toolstripbutton supposed to go in pnlMain, but the problem occurs that after logging in and click one of the toolstripbutton it quits the whole windows application.
I tried to search about these and I found almost the same as my problem but the solution I think is not for my problem because I think it is for two forms only and the main form will be put in program.cs, but i have 2 and I think but not sure that my main form is the login. Please enlighten me.
Thank you
Because of this line in your program.cs
Application.Run(new FrmLogin());
the form FrmLogin is the main form of your application.
When the main form of an application is closed, the application is terminated. I suppose that after Login, you do not close but only hide the login form.
However, your code in CloseAllActiveForms will also close the hidden login form.
A quick solution is probably to skip all hidden forms in CloseAllActiveForms or explicitly skip FrmLogin in CloseAllActiveForms.
public void CloseAllActiveForms()
{
List<Form> openForms = new List<Form>();
foreach (Form f in Application.OpenForms)
openForms.Add(f);
foreach (Form f in openForms)
{
if (f.Visible && !(f is FrmAdmin) && !(f is FrmLogin))
{
f.Close();
}
}
}
There are alternative cleaner solutions:
Show the login form from the main form. See how to show login form on front & Mainform Behind Login Form?
Pass an ApplicationContext instead of a Form to Application.Run. This allows you to have more control over when the application is closed. See Windows Forms: create the main application after login, which form to run?
Related
This is how I made the main form
Basically, I want to open a new form (dashboard) using a button inside the usercontrol. The usercontrol is fill in the mainform's panel (login).
private void btnSignIn_Click(object sender, EventArgs e)
{
if (txtUsername.Text == "admin" && txtPassword.Text == "admin")
{
MessageBox.Show("Login Successfully");
DASHBOARD dashboard = new DASHBOARD();
dashboard.ShowDialog();
}
}
I did try this block of code but it won't close the mainform
MainForm mainform = new MainForm();
mainform.Hide();
DASHBOARD dashboard = new DASHBOARD();
dashboard.ShowDialog();
mainform.Close();
This code creates a new instance and closes it hidden. However, this doesn't affect the main window as they are not related.
MainForm mainform = new MainForm();
mainform.Hide();
mainform.Close();
this.ParentForm.Hide(); can complete the operation of hiding the main window.
usercontrol:
code:
using System;
using System.Windows.Forms;
namespace WindowsFormsControlLibrary1
{
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (this.textBox1.Text == "admin" && this.textBox2.Text == "admin")
{
MessageBox.Show("Login Successfully");
UserForm dashboard = new UserForm();
this.ParentForm.Hide();
dashboard.ShowDialog();
this.ParentForm.Close();
}
else
{
MessageBox.Show("Login Error");
}
}
}
}
Mainform:
Output:
This is a WinForms app, I take it. You can't close the Main Form without terminating the application. The only thing running above that is the Program static instance. If I read this right, the effect you're looking for can be achieved with Panels. A panel is just a control that contains other controls. You can have a panel for login and another for dashboard and switch between them by the simple expedient of which one you decide is on top at any given moment.
Another possible approach is to make a tiny hidden Main Form whose sole function is to spawn other forms but it is never actually displayed at all.
I'm curious, though. Why don't you put the dashboard in the main form, and when the main form has loaded, have it spawn a Modal Login Dialog? Once login is complete, destroy the login dialog and the dashboard is now your main display by default, or if login fails, then you can keep respawning the login dialog until the login succeeds or you decide that the user is a Bad Actor and you abort the application entirely. It seems the login is the transient function, so code it as such.
I have a WinForm listbox selection of a list of forms that the user can go into.
I have a function that should open the new form
private void sendToDB_Button_Click(object sender, EventArgs e)
{
string selected_item = listBox1.SelectedItem.ToString();
Form _secondForm = new Form();
if (selected_item == "389")
_secondForm = new Forms._389_Form();
else if ( selected_item == "120" )
_secondForm = new Forms._120_Form();
//... Repeat for 30 more forms ...
this.Hide();
_secondForm.Show();
}
When running the application and I select "389" the current form closes as it should but nothing is opened in a new form. Curious if having the forms in a folder called Forms is the issue here. The line in question is _secondForm = new Forms._389_Form(); and is this breaking the application?
Instead of _secondForm.Show(); I changed it to _secondForm.ShowDialog(); and I got the expected results.
According to this link: https://stackoverflow.com/a/20859112/8149159 , The author of the answer states that:
The Show function shows the form in a non modal form. This means that you can click on the parent form.
ShowDialog shows the form modally, meaning you cannot go to the parent form
try
this.Hide();
_secondForm.ShowDialog();
//if you want close precedent form
this.Close();
Hide is for "hide" all action at the user
ShowDialog is for open the form and
Close is for close the precedent form
I have problem with passing references to my windows in WinForms project and then retrieving them.
I have Login form when I create another (Main) form and hidding Login form in button event(I don't want to destroy Login reference here so I keep it in static class) :
private void btnLog_Click(object sender, EventArgs e)
{
if (CheckIfPasswordIsCorrect((int)DataSetUsers.Tables[0].Rows[cmbUsers.SelectedIndex][0]
, txtPassword.Text.Trim()))
{
GlobalData.LoginFormRef = this; //passing reference to Login form into static class
this.Hide(); //hidding Login form
MainForm mainForm = new MainForm();
mainForm.Show();
}
else
{
MessageBox.Show("Wrong password");
txtPassword.Focus();
}
}
GlobalData is static class with static object GlobalData.LoginFormRef so I can keep my Login form reference.
Then if I log out from my main form and want to back to login form I get an error or simply my application turns off :
private void btnLogOut_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
GlobalData.LoggedUser = null;
if (GlobalData.LoginFormRef != null)
{
GlobalData.LoginFormRef.Show(); //trying to show my login form back
}
this.Close(); //closing Main form
this.Dispose(true); //destroying main form
}
When I'm closing my Main form and trying to invoke Login form back it disappears immediately or I'm getting an error System.ObjectDisposedException . I don't understand why. I have my reference to Login form in static class .... How can I destroy main form and show again Login form ?
Did you maybe start your application by using Application.Run(new MainForm())?
If you did, then it registered the closing event for MainForm with an event handler that closes the UI thread.
This will dispose all the forms including your login form (and will exit the application assuming you don't have any living non background threads).
See the remarks in msdn for Application.Run(Form): https://msdn.microsoft.com/en-us/library/ms157902(v=vs.110).aspx
I have designed a pos software.Here is a 3 form one login form,pos_authority form,pos_user form.in pos_authority and pos_user user form have an button for logout.when i click the button i want to logout from the form and want to show the login form.when i login i hide the login form.here is my code
private void blogout_button_Click(object sender, EventArgs e)
{
try
{
foreach (Form f in Application.OpenForms)
{
if (f.Name != "login_form")
{
f.Close();
new login_Form().Show();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
here show the exception
Collection was modified; enumeration operation may not execute.
Application.OpenForms is fetching all open forms at runtime, however if you close an open form (which in turn remove it from the OpenForm), the foreach statement will throw you exception saying the collection has been changed, which is true.
to workaround for this kind of problem, you could store the open forms into a list:
Application.OpenForms.Cast<Form>().ToList()
or traverse the collection the other way round - from the last to the first instead.
EDIT:
to get rid of the exception, replace your foreach (Form f in Application.OpenForms) with foreach (Form f in Application.OpenForms.Cast<Form>().ToList()), i did not test it, but it should work in theory.
But i don't think it will function well even if you correct the exception - you will end up with many login form shown if there are more than one opened form. i suggest you review your entire design and try to use event - you know windows forms are event driven!
Try this in your login form;
private void ButtonClick(object sender, EventArgs e)
{
Form aform = new Form();
aform.Show();
aform.FormClosing += FrmClosing;
Hide();
}
private void FrmClosing(object sender, FormClosingEventArgs e)
{
Show();
}
Basically, you listen (from the login form) to the form closing event for the other form and when it occurs, you show the login form again. Works a treat for my programs.
Your exception is because you are calling f.Close() which deletes de form, changing the collection which is looping in the foreach and thus being unable to continue looping.
And I think you should change your code from:
new login_Form().Show();
to:
login_Form.Show();
I am creating an app which currently has 3 forms,
Parent form - to accept login details from the user, validate and if successful hides itself and opens a child form.
1st Child form - on form load connects to the database fetches data and displays it. Click on new entry and another child form opens.
2nd child form - user enters new data for new entry in the database, on success a success message box comes up. user then may click on close button and this form hides itself and the 1st Child form is shown.
what i want to do is to find out someway to reload the 1st Child form, on closing thee 2nd Child form. This will result in the records being displayed in it to get refreshed and thus show the new entry that was just made using the 2nd Child form.
Please guide me as to how i can achieve this.
Here is the code that i used to handle the hide events.
In the main form on login event = true
cpanel child = new cpanel(); //create new isntance of form, cpanel is the 1st child form
child.FormClosed += new FormClosedEventHandler(child_FormClosed); //add handler to catch when child form is closed
child.Show(); //show child
this.Hide(); //hide parent
void child_FormClosed(object sender, FormClosedEventArgs e)
{
//when child form is closed, the parent reappears
MessageBox.Show("You have been logged out.");
Application.Exit();
}
In the 2nd child form i have something like this
private void button3_Click(object sender, EventArgs e)
{
this.Close();
}
Make your ChildForm1 to be main form:
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
using(var loginForm = new LoginForm())
if (loginForm.ShowDialog() != DialogResult.OK)
return;
Application.Run(new ChildForm1());
And show ChildFrom2 from ChildForm1 form:
Hide(); // you really don't need to hide main form
using(var childForm2 = new ChildForm2())
{
if (childForm2.ShowDialog() == DialogResult.OK)
{
// update ChildForm1 with data from ChildForm2
}
}
Show();
You can use this :
In 2nd Child form before closing:
childForm1.refresh()
In 1st Child form:
public static void refresh() //You can use it with parameters too
{
//do something
}
Ok once again i have finally solved the problem, and is posting the solution in hopes it will someday help someone with similar problem.
The actual solution is very simple really, here is what needed to be done.
add this line in the child form, somewhere in the protected section of 2nd Form other than inside a method so that it is always present.
cpanel child = new cpanel();
inside the close button method of the 2nd Form needs to be something like this.
private void button3_Click(object sender, EventArgs e)
{
child.Show();
this.Hide(); //hide parent
}
This will enable you to get an updated 1st Form when you click on the Close button of the 2nd Form after updating the contents.