-2

I have been looking for some time on ways to open a second form from another already shown form.

This is some piece of code that works:

frmSecond second = new frmSecond();
this.Hide();
second.ShowDialog();
this.Close();

What it does basically is to Hide() the currently opened form, then it opens another form (the ShowDialog() method). It will only Close() the currently hidden form when the form you have just created is closed.

The problem here is: this way of doing it creates an immense thread of forms. If I need to go from frmSecond to frmThird, it will maintain the first form and the frmSecond being executed in the background, while only showing the frmThird.

Then, as the frmThird is open, if I need to get back to the first form, I would use some code like:

frmFirst first = new frmFirst();
this.Hide();
first.ShowDialog();
this.Close();

And it would create another frmFirst! Then we would have three forms being executed in the background (the first frmFirst, frmSecond, and frmThird).

This method works, but uses an increasingly amount of processing memory, which may be prejudicial for any kind of project.

Is there any alternative or add up to correct this problem?

If anything is unclear, please don't bother in letting me know. Thank you.

  • you could use `using(Form f = new Form()) { f.ShowDialog(); }` it will automatically dispose of form when closed – Aleksa Ristic Nov 19 '18 at 00:02
  • 1
    Usually a winforms application will have a main form and open subsequent forms, Generally normal applications don't try to minimise the previous form, as the next child form is related to the previous one – TheGeneral Nov 19 '18 at 00:03
  • Secondly, when you are finished with a child form you close it, if its modal, you usually have it in a using statement, control goes back to your previous (non hidden form) and you dont have to create a new form – TheGeneral Nov 19 '18 at 00:07
  • 1
    Hide() does not hide anything from the machine, only from the user's eyes. [Look here](https://stackoverflow.com/a/10769349/17034) for a possible way to get ahead. – Hans Passant Nov 19 '18 at 00:50
  • The thing is: the form is already disposed (and closed) when the user come back from it, but I have a kind of complex menu structure, so it's not only one parent form and a bunch of children. What I'm trying to do is creating a menu, that redirects to a Sign in form that will, if the user and password are correct, show the user a dashboard, that will have a lot of other options. So there are dozens of parent/children relations, that create and need this enormous amount of processing memory. – Estêvão Rolim Nov 19 '18 at 03:00
  • Why do you create a new instance of the first form when `going back` to it ? Why not really go back to it instead of creating new forms like crazy ? Then you wont have so many forms open and your app will work faster also – GuidoG Nov 19 '18 at 12:43

3 Answers3

2

If you want to get access to already created forms try using the static Application.OpenForms property. It contains a list of all of the forms currently open in your application. Documentation is here.

As an example, if you always want to keep frmFirst open and then navigate back to it when you close one of your other forms you can do this:

frmFirst existing = Application.OpenForms.OfType<frmFirst>().FirstOrDefault();
if (existing != null)
    existing.Show();

You would need to remove your this.Close() calls for this to work.

Handbag Crab
  • 1,488
  • 2
  • 8
  • 12
  • This is awesome, but I'm not sure I'll be able to use it to every form opened in the project. In the main menu, the user will be redirected to a login form, where, if the user and the password is correct, he/she will be redirected to a dashboard, where he/she will have access to a bunch of other options (and forms). So this method is probably more practical if there are forms only with simple constructors, in this project's case, there are dozens of forms with a lot of different arguments. Guess I'll just need a lot of memory anyway, hehe – Estêvão Rolim Nov 19 '18 at 03:06
  • Perfect, Thank you very much! – Estêvão Rolim Nov 21 '18 at 19:43
  • So I've spent a bunch of days working on this solution, trying to use your code, Handbag, and it looks like this way is eating way more memory than the other one. – Estêvão Rolim Dec 10 '18 at 19:30
  • If you're using `ShowDialog()` to show either of your forms, you need to use `DialogResult = DialogResult.OK` to close them otherwise they never get disposed. If you're just using `Show()` then calling `Close()` is fine. My solution should use less memory as you only ever have one copy of frmFirst in memory. I would suggest putting a tracepoint in the designer.cs file for your forms in the Dispose methods then just have it print out that it's disposing. If you never see these messages then that's why your application is using up memory. – Handbag Crab Dec 10 '18 at 20:06
0

To free the memory you need to dispose the form using the Dispose method when it is no longer needed.

Ivan Ičin
  • 9,672
  • 5
  • 36
  • 57
0

Seems like you have a desing error here

Then, as the frmThird is open, if I need to get back to the first form, I would use some code like:

frmFirst first = new frmFirst();
this.Hide();
first.ShowDialog();
this.Close();

This will leave the original created frmFirst in memory, not visible, doing nothing but eating memory.
If you know you want to get back to frmFirst that was created before, why not just do this :

frmFirst.Show();

and save you lots of memory.

You have 2 choices actually

  1. Hide forms and reactivate them when needed
  2. Close and dispose forms, and recreate them when needed

What you are doing is creating each form over and over again, without getting rid of the prior created forms. Hence you need lots of memory for hidden forms...

GuidoG
  • 11,359
  • 6
  • 44
  • 79