7

in my application i have four forms form1 form2 form3 form4 .and each form have two buttons i.e next and previous buttons to switch between forms .and my question is how can i Switch between forms without creating new instance of forms? below is my code

In Form1:

    public Form1()
   {
       InitializeComponents();
   }

    private void Next_Click(object sender, EventArgs e)
    {
      this.Hide()
       Form2  form2 = new Form2();
       form2.Show();
    }      

In Form2:

    public Form2()
   {
       InitializeComponents();
   }
    private void Previous_Click(object sender, EventArgs e)
    {
       this.Hide();
       Form1 form1 = new Form1();
       form1.Show();
    }

    private void Next_Click(object sender, EventArgs e)
    {
         this.Hide();
       Form3 form3 = new Form3();
       form3.Show();
    }      

In Form3:

    public Form3()
   {
       InitializeComponents();
   }
    private void Previous_Click(object sender, EventArgs e)
    {
        this.Hide();
       Form2 form2 = new Form2();
       form2.Show();
    }

    private void Next_Click(object sender, EventArgs e)
    {
         this.Hide();
       Form4 form4 = new Form4();
       form4.Show();
    }      

In Form4:

    public Form4()
   {
       InitializeComponents();
   }
    private void Previous_Click(object sender, EventArgs e)
    {
         this.Hide();
       Form3 form3 = new Form3();
       form3.Show();
    }

In Main:

static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        Application.Run(new Form1());


    }

In above code i am creating new instances of forms every time..,How can i Avoid this and How can i Switch between forms without creating new instances of forms.... please help me

Sumeshk
  • 1,980
  • 20
  • 33
user3413736
  • 163
  • 1
  • 4
  • 11
  • 2
    Keep a public static variable of all forms in a global class. initialize form2, form3, form4 in the form1 initialize function. then just activate or hide as required. – ray Mar 13 '14 at 05:39
  • any o fthe answer is helpful to you please mark it as answer – Sumeshk Mar 13 '14 at 07:55
  • @ray Can you please post your answer as code? it might just do the job for me and I'll get a better understanding of what you are saying... :) – envyM6 Dec 17 '14 at 00:10

9 Answers9

8

Since you are accessing your forms sequentially just make sure that you use the Show Method that assigns the owner to the created Form and assign it to a class level variable after you create it. Something like this should work for you.

Form1

public partial class Form1 : Form
{
    Form2 frm2;
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (frm2 == null)
        {
            frm2 = new Form2();   //Create form if not created
            frm2.FormClosed += frm2_FormClosed;  //Add eventhandler to cleanup after form closes
         }

        frm2.Show(this);  //Show Form assigning this form as the forms owner
        Hide();
    }

    void frm2_FormClosed(object sender, FormClosedEventArgs e)
    {
        frm2 = null;  //If form is closed make sure reference is set to null
        Show();
    }
}

Form2

public partial class Form2 : Form
{
    Form3 frm3;
    public Form2()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Owner.Show();  //Show the previous form
        Hide();

    }

    private void button2_Click(object sender, EventArgs e)
    {
        if (frm3 == null)
        {
            frm3 = new Form3();
            frm3.FormClosed += frm3_FormClosed;
        }

        frm3.Show(this);
        Hide();
    }

    void frm3_FormClosed(object sender, FormClosedEventArgs e)
    {
        frm3 = null;
        Show();
    }
}

Form3

public partial class Form3 : Form
{
    public Form3()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Owner.Show();
        Hide();
    }
}
Mark Hall
  • 53,938
  • 9
  • 94
  • 111
4

Try This:

Form1 myForm =(Form1) Application.OpenForms["Form1"];
myForm.Show();
Sudhakar Tillapudi
  • 25,935
  • 5
  • 37
  • 67
  • But that requires that the forms are already open. And referencing forms by name I call ugly. – PMF Mar 13 '14 at 05:46
  • Despite @PMF 's comment it was exactly what I needed! Every other case that I could find only spoke of instantiating a new instance of the form... and in my case I wanted to manipulate a current form already open. – Anthony Griggs Jul 31 '17 at 19:24
4

May be a easy solution. You can make a class that contains static object of all forms that you need. So you will be able to access all these forms from any forms of your choice and the good thing is they are initialized once.

public class formList
{
      private static Form1 _form1 = new Form1();
      public static Form1 form1 { get {return _form1;}
      .................
      ............
}
Mehbube Arman
  • 472
  • 1
  • 7
  • 18
3

You can check if the form of interest exists, and if not create it:

public static T OpenOrCreateForm<T>() 
  where T: Form, new() {

  T result;

  // Test if form exists
  foreach(Form form in Application.OpenForms) {
    result = form as T;

    if (!Object.ReferenceEquals(null, result)) {
      // Form found; and this is the right place 
      //  to restore form size,
      //  bring form to front etc.
      if (result.WindowState == FormWindowState.Minimized)
        result.WindowState = FormWindowState.Normal;

      result.BringToFront();

      return result;
    }
  }

  // Form doesn't exist, let's create it
  result = new T();
  // Probably, you want to show the created form
  result.Show();

  resturn result;
}

...
private void Previous_Click(object sender, EventArgs e)
{
   Hide();
   OpenOrCreateForm<Form1>();
 }

private void Next_Click(object sender, EventArgs e)
{
   Hide();
   OpenOrCreateForm<Form3>();
}   
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
1
  public bool IsFormAlreadyOpen(Type FormType)
        {
            foreach (Form OpenForm in Application.OpenForms)
            {
                if (OpenForm.GetType() == FormType)
                    return true;
            }
            return false;
        }

This function can be used to find out whether a form is already opened or not

call IsFormAlreadyOpen(Form4) if it returns true which means Form4 is already opened

and in your case

in every forms constructor() create next and previous forms object

and in the button click calls IsFormAlreadyOpen() to find out whether the form is already opened or not and if it already opened just bring that form in front other wise display the form using obj.show() method and hide or close the parent form

Sumeshk
  • 1,980
  • 20
  • 33
0

Looks like you are trying to achieve wizard like feature. I would recommend having a single form. Then, add a customized tab control to it. Add buttons to form that moves previous and next.

To customize tab control, this is what you need to do:

public class CustomWizard : TabControl
{
    /// <summary>
    /// This method traps windows message and hides other tabs in the tab control.
    /// Message trapped: TCM_ADJUSTRECT
    /// </summary>
    /// <param name="m">Reference to Windows message</param>
    protected override void WndProc(ref Message m)
    {
        // Second condition is to keep tab pages visible in design mode
        if (m.Msg == 0x1328 && !DesignMode)
        {
            m.Result = (IntPtr)1;
        }
        else
        {
            base.WndProc(ref m);
        }
    }

    /// <summary>
    /// This method traps the press to stop users from selecting tab page via keyboard
    /// </summary>
    /// <param name="ke">Event details</param>
    protected override void OnKeyDown(KeyEventArgs ke)
    {
        if (ke.Control && ke.KeyCode == Keys.Tab)
            return;

        base.OnKeyDown(ke);
    }

    private void InitializeComponent()
    {
        this.SuspendLayout();
        this.ResumeLayout(false);

    }
}

This tab control will only display one tab at a time. Although, at design time you can see them all. Add this and buttons to your form. On button click, merely set the SelectedIndex property of this tab control.

danish
  • 5,550
  • 2
  • 25
  • 28
0

I had the same issue. An application I needed that had many forms and I needed to switch between forms forward n backward without losing the data. I came up with the following solution and it worked for me.

In the main (Program.cs) file, write the following two classes:

static class Variables
{
    public static DataSet Configurations = new DataSet();

    public static float ExchangeRate = 0;

    public static Dictionary<string, int> ItemsCategories = new Dictionary<string, int>();

    public static Dictionary<string, float> WeightUnits = new Dictionary<string, float>();
}

static class Forms
{
    public static Form2 F_Form2 = new Form2();

    public static Form3 F_Form3 = new Form3();
}

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    /// 
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

The first class is used for Global variables that can be used across the forms. You can access any variable by:

Variables.ExchangeRate = 7.2; //(for ex).

The second class is where you define new instance of all your forms. You can hide n show them anywhere across all the forms by:

Forms.F_Form3.Show();

or

Forms.F_Form2.Hide();

This works smoothly and perfect for me. Try it.

0

Just remove the this.hide() in the first form and the [formNameHere].show(); in the second form.

Like this:

Form 1:

public Form1()
{
    InitializeComponents();
}

private void Next_Click(object sender, EventArgs e)
{
    this.Hide()
    Form2  form2 = new Form2();
    form2.Show();
} 

Form 2:

public Form2()
{
    InitializeComponents();
}

private void Previous_Click(object sender, EventArgs e)
{
    Form1 form1 = new Form1();
    this.Hide();
}

private void Next_Click(object sender, EventArgs e)
{
    Form3 form3 = new Form3();
    this.Hide();
}  

etc.. not good at explaining, and with C# really. But this should work.

Mika Sundland
  • 18,120
  • 16
  • 38
  • 50
designdust
  • 109
  • 1
  • 4
0
    //In Form1
private static Form1 i_Instance = null;
public static Form1 Instance
   {
      get
      {
        if (Form1.i_Instance == null) Form1.i_Instance = new Form1();
        return Form1.i_Instance;
      }
   }
// And instantiation in other forms shall look like following
Form1 F1 = Form1.Instance;
F1.Show();
  • This works if I choose say Form0 as the main form (Application.Run(new Form0()) and open other forms from this form. Please note that method will not work if Form0 instantiation attempts are made from any of the instances (there will be only one of each) of other forms that are invoked from Form0. In this case program does compile but not run – Murat TC Tokgozlu Dec 23 '21 at 16:11