11

How do i show a from that have been hidden using

this.Hide();

I have tried

MainMenuForm.Show();

and this just says i need an object ref. I then tried:

MainMenuForm frmMainMenu = new MainMenuForm();
frmMainMenu.Show();

Which seems to show the appropriate form. But when you exit the app, it is still held in memory because it hasn't shown the form that was hidden, instead it has shown a new version of the form. In effect having 2 instances of the form (one hidden, one visible).

Just to clarify, the MainMenuForm is the startup form. When (for example) Option 1 is clicked, the MainMenuForm then hides itself while opening up the Option 1 form. What i would like to know is how to i make the Option 1 form that the MainMenuForm opens "unhide" the MainMenuForm and then close itself.

What's the correct procedure here?

Thanks in advance.

Arcadian
  • 1,373
  • 4
  • 20
  • 30

7 Answers7

25

When you do the following:

MainMenuForm frmMainMenu = new MainMenuForm();
frmMainMenu.Show();

You are creating and showing a new instance of the MainMenuForm.

In order to show and hide an instance of the MainMenuForm you'll need to hold a reference to it. I.e. when I do compact framework apps, I have a static classes using the singleton pattern to ensure I only ever have one instance of a form at run time:

public class FormProvider
{
   public static MainMenuForm MainMenu
   {
       get
       {
          if (_mainMenu == null)
          {
            _mainMenu = new MainMenuForm();
          }
          return _mainMenu;
       }
   }
   private static MainMenuForm _mainMenu;
}

Now you can just use FormProvider.MainMenu.Show() to show the form and FormProvider.MainMenu.Hide() to hide the form.

The Singleton Pattern (thanks to Lazarus for the link) is a good way of managing forms in WinForms applications because it means you only create the form instance once. The first time the form is accessed through its respective property, the form is instantiated and stored in a private variable.

For example, the first time you use FormProvider.MainMenu, the private variable _mainMenu is instantiated. Any subsequent times you call FormProvider.MainMenu, _mainMenu is returned straight away without being instantiated again.

However, you don't have to store all your form classes in a static instance. You can just have the form as a property on the form that's controlling the MainMenu.

public partial class YourMainForm : Form
{
   private MainMenuForm _mainMenu = new MainMenuForm();

   protected void ShowForm()
   {
      _mainMenu.Show();
   }

   protected void HideForm()
   {
      _mainMenu.Hide();
   }
}

UPDATE:

Just read that MainMenuForm is your startup form. Implement a class similar to my singleton example above, and then change your code to the following in the Program.cs file of your application:

Application.Run(FormProvider.MainMenu);

You can then access the MainMenuForm from anywhere in your application through the FormProvider class.

Community
  • 1
  • 1
djdd87
  • 67,346
  • 27
  • 156
  • 195
  • 1
    Singleton in C# is better achieved using the examples here: http://www.yoda.arachsys.com/csharp/singleton.html – Lazarus Jun 09 '10 at 12:41
  • 3
    @Lazarus - I kept the pattern simple as it's not particular relavent to the question and didn't want to confuse the OP. – djdd87 Jun 09 '10 at 12:45
  • 3
    @GenericTypeTea, good point :) +1 - That said, he didn't specifically request a singleton either so that pattern may need further explanation. – Lazarus Jun 09 '10 at 12:52
  • 2
    @Lazarus - Quite agreed. I was just trying to show a few different ways of holding a reference to the form which is the underlying problem. – djdd87 Jun 09 '10 at 13:01
  • Yeah, i figured that it was simply creating a new instance. I'll try out your code and see what happens – Arcadian Jun 09 '10 at 13:06
  • @Arcadian, I'll revisit this question every 10 mins or so. So if you have any questions, feel free to leave a comment here. – djdd87 Jun 09 '10 at 13:13
  • hmmm, is that code supposed to go on the MainMenuForm or does it go on the Option 1 form? – Arcadian Jun 09 '10 at 13:21
  • From the MainMenuForm itself you can call this.Hide(). When you want to reshow it from another form, you have to call .Show() on the property that has a reference to it. – djdd87 Jun 09 '10 at 13:24
  • Ok just to be clear, does the formprovider class need to be on the mainmenu itself, or on the form that shows the mainmenu, i.e Option 1 Also i changed the Application.Run line on the Program.cs file and now i get an error saying that it doesn't exist in the current context. – Arcadian Jun 09 '10 at 13:41
  • All classes should go in their own file. Right click on your project, select "Add Class...". Type the name "FormProvider". Press enter. You will now have a new class. Put in the "public static MainMenuForm MainMenu... etc" code and ensure that the class is set to public as per my example. – djdd87 Jun 09 '10 at 13:45
  • right, i get it. then u just use FormProvider.MainMenu.Show(); that right? – Arcadian Jun 09 '10 at 14:06
  • You sure you ticked it up ;)? Since you posted that comment I lost one upvote - hehe. Perhaps you unticked it by mistake? And no problem, glad it's all working. – djdd87 Jun 09 '10 at 16:21
  • you didn't lose it from me. its ticked and rep'd by me. – Arcadian Jun 09 '10 at 22:23
  • Programmers such as YOURSELVES are motivation for programmers such as us. Thanks for such an incredible solution! – Muneeb Mirza Sep 07 '14 at 20:21
  • @GenericTypeTea - I was trying this for my application, but keep getting a StackOverflowException `public partial class frmLogin : Form` `{` `// The following causes a StackOverflowException:` `private frmLogin _frmLogin = new frmLogin();` `}` – Tornado726 Sep 05 '16 at 21:31
  • @Tornado726 You're creating "frmLogin" within "frmLogin". So _frmLogin's instance also creates a private _frmLogin, which then creates a _frmLogin instance, etc, etc. Look at my code, I'm creating a "Main"MenuForm within a "Your"MenuForm. Two different classes – djdd87 Sep 06 '16 at 07:51
  • Singleton page by @Lazarus has new location http://csharpindepth.com/Articles/General/Singleton.aspx Also noted on old page.. – B. Shea Oct 17 '16 at 16:02
  • Was looking for it for a long time, finally found it – mvikhona May 01 '20 at 15:10
3

The simplest and easiest way is to use LINQ and look into the Application.OpenForms property. I'm assuming you have only 1 instance of the form (hopefully!), otherwise make sure to have to have some public property on the hidden form to be able to differentiate it.

The following code will un-hide the form for you:

var formToShow = Application.OpenForms.Cast<Form>()
    .FirstOrDefault(c => c is MainMenuForm);
if (formToShow != null)
{
    formToShow.Show();
}
code4life
  • 15,655
  • 7
  • 50
  • 82
1

Practically This works for me....

public class MainWindow : Form
{
    Form _mainMenuForm = new MainMenuForm();
}

calling it through a button click event.

private void buttonclick()
{
    if (_mainMenuForm.Visible)
    {
         _mainMenuForm.Visible = false;
    }
    else
    {
         _mainMenuForm.Visible = true;
    }
}
DanM7
  • 2,203
  • 3
  • 28
  • 46
Padhu
  • 1,590
  • 12
  • 15
1

You need to keep a reference to the first form when it's created and then the code that holds that reference can call Show on it.

If you don't open that form from somewhere but it's set as the startup form, then you either need to change it so that you have a Main method that opens that form or you can have that form store a reference to itself somewhere that can be accessed from other places.

For example, an quick and ugly way would be to, add a public static property to your mainform and then when you hide the form it also writes this to that property which can then be retrieved when needed by other parts of the code.

Hans Olsson
  • 54,199
  • 15
  • 94
  • 116
0

Call the referenced form.

Like:

Calling parent
----------
public MyForm f {get;set;}

void DoStuff()
{
f = new MyForm();
f.Show();
}

MyForm
----------
void DoOtherStuff()
{
this.hide();
}

Parent
----------
void UnHideForm()
{
f.show();
}
djdd87
  • 67,346
  • 27
  • 156
  • 195
Ralf de Kleine
  • 11,464
  • 5
  • 45
  • 87
0

Store a reference to the form and call .Hide() and .Show() on that.

For example:

public class MainWindow : Form
{
    private Form _mainMenuForm = new MainMenuForm();

    public void btnShowMenuForm_Click(...)
    {
        _mainMenuForm.Show();
    }

    public void btnHideMenuForm_Click(...)
    {
        _mainMenuForm.Hide();
    }

    //etc
}

This example assumes you have a form which is launching the MainMenuForm.

Paolo
  • 22,188
  • 6
  • 42
  • 49
-1

Another simpler method to achieve this is to loop through the open forms to see which are still running and open it...

foreach (Form oForm in Application.OpenForms)
{
   if (oForm is MainMenuForm)
   {
      oForm.Show();
      break;
   }
}
  • 1
    Just out of curiosity, why was this answer voted down? Is it bad practice? Is it not efficient? If I'm making a mistake a comment to let me know would be more helpful than a downvote by itself. Thanks in advance. – RunninThruLife Mar 25 '14 at 19:38