hi there,

i am creating an application in visual studio 2008 standard edition. i have a form all frmMainMenu and a frmLogin and a frmAddNewProposal.

i have a close button in frmMainMenu, i want to coed this so that when i click on the close button the frmLogin should appear. and also when i click on the frmMainMenu right hand side close icon in the from the same should happen.

in the fromClosing event I wrote the code as

new frmLogin().show();
this.close();

and also in the close button i wrote the code as

new frmLogin().show();
this.close();

but there is an error occuring??
i have asked this question previously also, but it was not clear and how do you handle this when there are multiple forms.

how can i solve this question?

thanxxx

Try something along these lines:

this.Hide();
Form_Login form_login = new Form_Login();
form_login.Owner = this;
form_login.Show();

your question is a little vague, could you please be more clear.
am sry, I didnt understand what your requirement is.

in the fromClosing event I wrote the code as

is this fromClosing event means the Dispose method? if no Place the code inside the Form Dispose method.

new frmLogin().show();

Please Try to give the code in details.

If frmMainMenu is your main application form then closing it will terminate the application.
What is the purpose of the login on form close?
If your intention is to check that the user has permission to close the application then :

  • In the close button just do this.close(); ; this will trigger form_closing.
  • In form_closing you need to test the result from your frmLogin and either allow the close or set the e.Cancel = true; to prevent the form from closing.

[EDIT] P.S. In form_closing you do not need this.close(); as the form is already closing!

Edited 6 Years Ago by nick.crane: Added P.S.

You don't have to.
It is ok to have more than one form open at a time.
To block access to the calling form when you open a dialog (eg frmLogin) use the ShowDialog method instead of Show.

As stated, your question is a little vague.
Do you need the user to be logged in before they can close frmMainMeny, or does the user log in before they can view frmMainMenu and when the form is closed you want to return to the login screen?

If its the first, display the login form in dialog mode to prevent the main menu form from continuing until it returns:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Form1 login = new Form1();
            if (login.ShowDialog() != DialogResult.OK)
                e.Cancel = true;
        }

Then in your login form set the this.DialogResult = DialogResult.OK when the user correctly validates their credentials.
This way if they fail the login the form will not close.

If its the second thing, and you want the user sent back to the login form when they clsoe the main menu then make frmLogin your main application form. When the user correctly logs in you create an instance of the main menu form and display it then return to the login form when it is closed.

Why did you want to close form1? If the instance of form2 is created within form1 then closing form1 would dispose of both.

If you let us know exactly what you want the forms to do we can better advise on the order and method of creating/opening each.

As stated, your question is a little vague.
Do you need the user to be logged in before they can close frmMainMeny, or does the user log in before they can view frmMainMenu and when the form is closed you want to return to the login screen?

If its the first, display the login form in dialog mode to prevent the main menu form from continuing until it returns:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Form1 login = new Form1();
            if (login.ShowDialog() != DialogResult.OK)
                e.Cancel = true;
        }

Then in your login form set the this.DialogResult = DialogResult.OK when the user correctly validates their credentials.
This way if they fail the login the form will not close.

If its the second thing, and you want the user sent back to the login form when they clsoe the main menu then make frmLogin your main application form. When the user correctly logs in you create an instance of the main menu form and display it then return to the login form when it is closed.

hey,

i cannot get the thing you are saying.

my requirment is the user logins through the frmLogin and if the login credinals are true the frmLogin is closed and the frmMainMenu should be displayed. and also when a button in the frmMainMenu is clicked another form which is the frmThree should be opened and the frmMainMenu shold be closed. so in this case i have a close button which will close the current form and open the previous form.


for example in the frmThree it should be like the code below

new frmMainMenu().show();//display the main menu form
this.Close(); // close the form three

but when i try to code the frmClosing of the frmThree as below(which should be closing the frmThree from and then displaying the frmLogin)

new frmLogin().show();
this.close();

but the thing is there is an error loop going on 
how can i avoid this and code it properly.

at one time i want only one form to be opened in the screen..........
thanxxxxxxxxxx

How does frmLogin decide if it should go to frmMainMenu or frmThree?
Show your code for this please.

Edited 6 Years Ago by nick.crane: n/a

Have you ever worked with VB6? The way you are trying to do this is how VB6 used to do it...a friend of mine always had trouble with .net forms.

When you create a form INSIDE another form, eg:

public partial class frmLogin : Form
    {

        //create instance of form
        private frmMainMenu mainMenu = new frmMainMenu();
    }

The new form is held in memory as a member of the containing form. When you call frmLogin.Close(), all of its members are disposed along with the form.
Here's an analogy to help:

You take a cardboard box, lets call it boxA.
You then take a second cardboard box...boxB.
You place boxB INSIDE boxA.

This is what happens in memory when you create frmMainMenu within frmLogin.

Now what happens if you throw boxA in the trash? boxB is in the trash as well.

This is what happens when you call frmLogin.Close().

I'm not trying to be condescending, but i always find a real world example helps to bring things into perspective.

Now, you have two choices here. You can either create a base form which will be created when you run your application and create all your other forms within it.
Or you can nest your forms and use frmLogin.Visible = false instead of frmLogin.Close(). By hiding the form, it is no longer shown to the user but remains in memory along with the forms you created within it.

Does that make it any clearer?

How does frmLogin decide if it should go to frmMainMenu or frmThree?
Show your code for this please.

hey whe the login credinals are corrent it closes the logi form and open the maina menu and when a button is clicked in the main menu the main menu is closed and the third for is opened . this is how it works .

the thing is is should be vise versa also

and when every interface is closed from the right hand corner close icon, it should close the form and onen the frmlogin.

but the thing is there is an error when i do this

thankxxxxx

Is this what you want to happen?

Run App
  |
  frmLogin <------------------
  |                          ^
  Credential                 |
  OK       Not OK ------------
  |                          |
  frmMainMenu                ^
  |         |                |
  Button   frmMainMenu Close -
  |                          | 
  frmThree                   ^
  |                          |
  frmThree Close -------------

If so, how is you app closed?

Edited 6 Years Ago by nick.crane: n/a

Is this what you want to happen?

Run App
  |
  frmLogin <------------------
  |                          ^
  Credential                 |
  OK       Not OK ------------
  |                          |
  frmMainMenu                ^
  |         |                |
  Button   frmMainMenu Close -
  |                          | 
  frmThree                   ^
  |                          |
  frmThree Close -------------

If so, how is you app closed?

yeah exactly,

only from the frmLogin
when the frmclosing event trigger and the cancel button is clicked in the frmLogin form
in this i wrote the code as Application.Exit();

thankxx

Heres an example of how to open frmMainMenu from frmLogin. As i explained, you can't close the parent form if you have created the child form within it so you have to hide the parent instead.

public partial class frmLogin : Form
    {

        //create instance of form to show when user logs in
        private frmMainMenu mainMenu = new frmMainMenu();

        public frmLogin()
        {
            InitializeComponent();

            //bind handler to form closed event so login form can react to main menu being closed
            mainMenu.FormClosed += new FormClosedEventHandler(mainMenu_FormClosed);
                 
        }

        //mock login method
        private void LogIn(string username, string password)
        {
            //obviously your login process will be much more secure ;)
            if (username == "Username" && password == "Password")
            { 
                //hide login form
                this.Visible = false;

                //reset main form - clear any changes made previously and reinstantiate if disposed
                mainMenu = new frmMainMenu();

                //show main menu
                mainMenu.Show();
            }

        }

        //when main menu is closed, unhide login form
        void mainMenu_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.Visible = true;
        }

        //button to test login process
        private void button1_Click(object sender, EventArgs e)
        {
            LogIn("Username", "Password");
        }
    }

You can do the same thing inside frmMainMenu to show your third form, then just close frmMainMenu in the frm3_Closed event handler.

Actually, I think this is what you want to happen.

Run App
        |
      frmLogin <--------------------
        |                           ^
      Credential                    |
        OK       Not OK ------------>
        |                           |
 ---> frmMainMenu                   ^
 |       |      |                   |
 ^     Button  frmMainMenu Close ->-|
 |       |                          | 
 ^   frmThree                      ^
 |    |     |                       |
 -- Button  |                       ^
            |                       |
        frmThree Close -->------>---

(modified to include button from frmThree)

As Ryshad said, set frmLogin as the startup form.

You will need to have a variable to keep track of frmLogin.
E.g public static frmLogin myLoginForm; And add myLoginForm = this; to form_load for frmLogin.

Use frmLogin.myLoginForm.Show(); and frmLogin.myLoginForm.Hide(); to make the login window appear and disappear as needed.

Edited 6 Years Ago by nick.crane: n/a

Actually, I think this is what you want to happen.

Run App
        |
      frmLogin <--------------------
        |                           ^
      Credential                    |
        OK       Not OK ------------>
        |                           |
 ---> frmMainMenu                   ^
 |       |      |                   |
 ^     Button  frmMainMenu Close ->-|
 |       |                          | 
 ^   frmThree                      ^
 |    |     |                       |
 -- Button  |                       ^
            |                       |
        frmThree Close -->------>---

(modified to include button from frmThree)

As Ryshad said, set frmLogin as the startup form.

You will need to have a variable to keep track of frmLogin.
E.g public static frmLogin myLoginForm; And add myLoginForm = this; to form_load for frmLogin.

Use frmLogin.myLoginForm.Show(); and frmLogin.myLoginForm.Hide(); to make the login window appear and disappear as needed.

hey but my question is not with the login form but with the other forms

when i write the code from the close button and the frmclosing event error appears,

thanxxxxxx

Without knowing hte error code or seeing all of your code it is hard to say for sure...but i think the problem is your recursive call to this.close().
Clicking the 'X' button at top right of form calls this.Close() and clicking your own close button calls this.Close().
When this.Close() is called it fires the FormClosing event, which shows a new instance of your form then calls this.Close(), which causes FormClosing to fire, creating a new isntance of your form and calling this.Close()...etc.

You should NOT have this.Close() in the FormClosing event handler. You will end up in an infinite loop.

More importantly, what nick and i have been trying to point out is a better method for working with nested forms. Have you even tried the code i showed you? It does exactly what you said you need it to do.
When the user logs in correctly it shows the main menu form. When the main menu form is closed it returns to the login form.

Please post the error message you are getting!!!!!
We are not mind readers here.

i have mentioned it previously in the post, but not sure whether it was understood???
in frmMainMenu

private void btnPinP_Click(object sender, EventArgs e)
        {
            new frmPP().Show();
            this.Hide();
        }

        private void btnBack_Click(object sender, EventArgs e)
        {
            frmLogin frmL = new frmLogin();
            frmL.Show();
            this.Close();
        }

        private void frmMainMenu_FormClosing(object sender, FormClosingEventArgs e)
        {
            frmLogin frmL = new frmLogin();
            frmL.Show();
            
        }

when i edit this code and write it in the third form and trigger the frmclosing event and "invalid operation exception" is occured.
in the below code

private void frmLogin_FormClosing(object sender, FormClosingEventArgs e)
        {
            Application.Exit();
        }

frmthree code

private void btnAddNewProposal_Click(object sender, EventArgs e)//when this button opens opens a new from and closes the current from
        {
            new frmAddNewProposal().Show();
            this.Close();
        }


  private void btnClose_Click(object sender, EventArgs e)//when this button is clicked the current from should close and the login from should appear
        {
            this.Close();
            
        }

private void btnBack_Click(object sender, EventArgs e)//this is to go to the previous from
        {
            new frmMainMenu().Show();           
            this.Hide();
        }


 private void frmPP_FormClosing(object sender, FormClosingEventArgs e)
        {
            frmLogin frmL = new frmLogin();
            frmL.Show();
        }

thnakxxx

As I have said before, if frmLogin is your start-up form then when it closes, your application is closing.
You do not need Application.Exit(); in the frmLogin_FormClosing event.
Your application is already in the process of closing!!!

Edited 6 Years Ago by nick.crane: n/a

Ok...i'm not sure you have fully understood what we have been trying to say. Please go back and read my example with the boxes because this:

frmLogin frmL = new frmLogin();
            frmL.Show();
            this.Close();

Is not the correct way to do it. Technically it shouldnt even work, but it does because of a slight quirk in the way .net disposes of forms. The form will be disposed once all references to it are remvoed, but the child form will have a reference to its owner so they hang around in memory.
But every time you create a new form you leave the old ones in memory. This will become VERY innefficient if the programme is used for any length and may even cause a buffer overflow : /

This is a simple design idea which nick showed perfectly with his flow diagrams. Instead of creating a NEW frmLogin every time the main menu is closed you should create a SINGLE instance of frmLogin as your base form. From that you create a SINGLE instance of main menu, and within mainmenu you create a SINGLE instance of your third form. When the third form is closed you return to the EXISTING frmMainMenu and likewise, when frmMainMenu is closed you return to the EXISTING frmLogin. This way you only ever have one instance of each form in memory and they are corectly garbage disposed when they are closed.

The code i posted shows how to create, show and close a single instance of frmMainMenu from within your base frmLogin. Please take the time to look at the code. If we help you get your existing code running we will be perpetuating a terrible design and us or another solver will eventually have to try and trouble shoot your memory issues further down the line.

You came here to ask for our help, and we are trying to give you the best advise we can. Please take the time to read and consider what were saying.

Comments
Well said
This article has been dead for over six months. Start a new discussion instead.