How can I properly manage instances of forms when hiding and showing in C#?

  • Context: C# 
  • Thread starter Thread starter madmike159
  • Start date Start date
  • Tags Tags
    Forms
Click For Summary
SUMMARY

This discussion focuses on managing multiple forms in C# without losing data when switching between them. The user initially created new instances of forms each time they were shown, leading to default values being displayed. The solution involves declaring form instances as class-level variables, allowing the forms to retain their state. The recommended approach is to initialize the form instances in the constructor of the main form and use the instance variable to show or hide the forms.

PREREQUISITES
  • Understanding of C# Windows Forms programming
  • Knowledge of object-oriented programming concepts, specifically classes and instances
  • Familiarity with event handling in C#
  • Basic understanding of form visibility management in C#
NEXT STEPS
  • Implement instance variables for form management in C# Windows Forms
  • Explore the use of the OwnedForms property for managing multiple forms
  • Learn about form constructors and their role in initializing form state
  • Research best practices for naming conventions in programming for better code clarity
USEFUL FOR

C# developers, particularly those working with Windows Forms, who need to manage multiple forms while preserving user input and state across form transitions.

madmike159
Gold Member
Messages
369
Reaction score
0
In VB6 this was very easy. you just used

Code:
form1.hide
form2.show

In c# you have to do this

Code:
form2 openForm2 = new form2(); //create a new instance
form2.show();
this.hide();

When I put this in a button it worked, but every time I changed forms it reset the form values to default (e.g. text boxes would become blank etc).
I was told this create a new instance every time, which was then lost so it would create a new instance every time with default values. So it put the form2 openForm2 = new form2(); at the top of the form code and have only kept the form2.show(); and this.hide(); in the button click.

The problem I now have is that because I need to declare an instance of each of my three forms I am causing a stack overflow.

How can I show and hide forms without the data disappearing? Where should I create these instances?
 
Technology news on Phys.org
madmike159 said:
In VB6 this was very easy. you just used

Code:
form1.hide
form2.show

In c# you have to do this

Code:
form2 openForm2 = new form2(); //create a new instance
form2.show();
this.hide();
This code looks wrong to me. Apparently form2 is some type (i.e., class) that you have defined, and openForm2 is an instance of that class.

To show openForm2 (not form2), do this:
Code:
form2 openForm2 = new form2(); //create a new instance
openForm2.show();

You don't give enough context for me to know what this code does.
Code:
this.hide();
madmike159 said:
When I put this in a button it worked, but every time I changed forms it reset the form values to default (e.g. text boxes would become blank etc).
I was told this create a new instance every time, which was then lost so it would create a new instance every time with default values. So it put the form2 openForm2 = new form2(); at the top of the form code and have only kept the form2.show(); and this.hide(); in the button click.

The problem I now have is that because I need to declare an instance of each of my three forms I am causing a stack overflow.

How can I show and hide forms without the data disappearing? Where should I create these instances?
 
Well when I try form2.show(); or form2.hide(); it says form2 does not have those argument or values.

So I do form2.

and show and hide don't appear in the list.

How would you hide and show a form? I created these forms using the add item option in visual studio, and the code op show another form needs to go into a button on a different form.
 
From your C# code, it appears that form2 is the name of the class and openForm2 is the name of an instance of the form2 class.

I think you are confused between the difference between a class and an object (an instance of a class).

Try something like this.

Code:
using System.Windows.Forms;
.
.
.
Form myForm = new Form(); // Create a new instance of the Form class.
myForm.Show(); // Show the form.
.
.
.
myForm.Hide(); // Hide the form.
 
Ok let me try and explain again.

This is at the top of my Form1.cs file

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SRV_GUI
{
    public partial class SRSV : Form
    {

        double oldGPSNorth = 0;
        double oldGPSEast = 0;
        int oldBearing = 0;
        int oldBatteryLevel = 0;
        
        public SRSV()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

Then in a button I have

Code:
 private void button2_Click(object sender, EventArgs e)
 {
      //This button opens the Test form and hides the main form
      Test openTest = new Test();
      openTest.Show();
      this.Hide();
}

Which refers to this form

Code:
namespace SRV_GUI
{
    public partial class Test : Form
    {
        public Test()
        {
            InitializeComponent();
        }

I want to be able to hide the first form (which was called form1 by default, but I changed to SRSV), and to show Test (originally called form2).

When I have Test openTest = new Test(); in a button it causes the forms to have their default values when they are shown again since I keep creating different instances of them.

I can do Test.Show() as this gives errors (Error 1 An object reference is required for the non-static field, method, or property) or Form2.Show() (Form2 doesn't exist in the current context)
 
try:Test openTest = new Test();
private void button2_Click(object sender, EventArgs e)
{
//This button opens the Test form and hides the main
openTest.Show();
this.Hide();
}
 
madmike159 said:
Ok let me try and explain again.

This is at the top of my Form1.cs file

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SRV_GUI
{
    public partial class SRSV : Form
    {

        double oldGPSNorth = 0;
        double oldGPSEast = 0;
        int oldBearing = 0;
        int oldBatteryLevel = 0;
        
        public SRSV()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

Then in a button I have

Code:
 private void button2_Click(object sender, EventArgs e)
 {
      //This button opens the Test form and hides the main form
      Test openTest = new Test();
      openTest.Show();
      this.Hide();
}

Which refers to this form

Code:
namespace SRV_GUI
{
    public partial class Test : Form
    {
        public Test()
        {
            InitializeComponent();
        }

I want to be able to hide the first form (which was called form1 by default, but I changed to SRSV), and to show Test (originally called form2).

When I have Test openTest = new Test(); in a button it causes the forms to have their default values when they are shown again since I keep creating different instances of them.
Test is the name of the class. openTest is an instance of the Test class.
madmike159 said:
I can do Test.Show() as this gives errors (Error 1 An object reference is required for the non-static field, method, or property) or Form2.Show() (Form2 doesn't exist in the current context)
You don't want to call Show() on the class - call it on the instance you created, openTest, as in
Code:
openTest.Show();

You really need to understand the difference between a class (e.g., Test) and an instance of the class (e.g., openTest). Once you create an instance of the class, then you can call the class methods. It is possible to call some methods on the class itself, but I don't think you're at the stage yet to understand this fine point.
 
I get what you are saying about openTest. The problem is that I don't know where to define

Code:
Test openTest = new Test();

Because if I do it in the button click code it works, but the form labels and text boxes go back to their default values every time, which is irritating.

I tried doing this at the beginning of each partial class bit, but this gave me stack overflow errors.
 
  • #10
If you define openTest inside the body of a method, as you showed in post #6, the scope of openTest is just the method in which it is defined. In other words, it is not visible outside your Click event handler.
Code:
private void button2_Click(object sender, EventArgs e)
 {
      //This button opens the Test form and hides the main form
      Test openTest = new Test();
      openTest.Show();
      this.Hide();
}
The net effect of this is, after the Click event handler is finished, then openTest ceases to exist. This is why the form labels revert to their values in the other form.

One possible fix would be to use the OwnedForms property on your form. This is an array of Form objects that is owned by the top-level Form. After you have initialized the 0-element of this array with the openTest form, you could do something like this:
Code:
this.Hide(); // Hide the SRSV form. 
this.OwnedForms[0].Show(); // Show the openTest form

I haven't tried this, so I can't guarantee it will work for you.

BTW, you ought to choose some better names for your forms. openTest gives no clue that it is the name of a form. A better name would be testForm.
 
  • #11
Ok thanks, I will try this.

I rarely program something where other people will have access to the source code, which is often why I do things that are unclear and make stupid mistakes.
 
  • #12
madmike159 said:
I rarely program something where other people will have access to the source code, which is often why I do things that are unclear and make stupid mistakes.
Most everyone makes dumb mistakes from time to time, but you make life much more difficult than it needs to be when your code is unclear. If your variable names aren't chosen so that their purpose is clear, anyone reading your code, including yourself, will have a harder time trying to figure it out.
 
  • #13
Keep track of the other form using a field in your main form:

Code:
namespace SRV_GUI
{
    public partial class SRSV : Form
    {
        private TestForm _otherForm; // instance variable (field) in your main form

        //... other stuff happens
        public SRSV()
        {
            InitializeComponent();
            _otherForm = new TestForm(); // initialize once in constructor
            _otherForm.Hide();
        }

        
        private void button2_Click(object sender, EventArgs e)
        {
            // only do toggle logic in the button click event handler.
            _otherForm.Show();
            this.Hide();
        }
    }
}
 

Similar threads

Replies
2
Views
2K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 49 ·
2
Replies
49
Views
12K
  • · Replies 25 ·
Replies
25
Views
5K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 5 ·
Replies
5
Views
5K
Replies
3
Views
3K
Replies
5
Views
41K
Replies
3
Views
4K