locked
How to simultaneously work with multiple forms in a single winform application without reloading the form when switched. RRS feed

  • Question

  • I have a winform application with multiple forms in it. When I go from one form to another , the form gets reloaded every time. I want the page to be resumed from where it was alredy . Please help with this. 
    • Moved by CoolDadTx Wednesday, February 5, 2020 2:46 PM Winforms related
    Wednesday, February 5, 2020 5:43 AM

All replies

  • There are probably a 100 ways to skin the cat.  The problem is that you aren't really telling the forum anything they can use to help you.

    "When I go from one form to another, the form gets reloaded every time."  Well, I can only guess that you've written code that actually deliberately works this way.  When you initialize a Form and call the Show() function, it's shown and it stays on the screen until you close it via GUI or call the Close() or Hide() functions on it.  It sounds like you're closing the form every time you display it, then re-initializing it every time you click a button or some other GUI element.

    "I want the page to be resumed from where it was already."  If you didn't ever close the form, it would behave this way.  Period.

    Unless you're working in ASP, not WinForms, but you're saying "form" for some reason.

    A look at the code for the form that generates forms and for the forms generated would be nice.

    Wednesday, February 5, 2020 6:49 AM
  • Hi varun_bwazz,
    You can use Hide method to conceal the form and use Show methods to resum from where it was alredy.
    Best Regards,
    Daniel Zhang


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, February 5, 2020 8:44 AM
  • I have attached the code of two forms Form1.cs and Battery.cs. 

    So within the Form1 there is a navigation panel where there are several buttons to call other forms.

    When I click on battery status , respective form will open and when I go back to dash board and click on battery status it will reload . I dont want that to happen.

     

    // Form1.cs

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.IO.Ports;

    namespace DarkDemo
    {
        public partial class Form1 : Form
        {

            private bool dragging = false;
            private Point startpoint = new Point(0, 0);
            public Form1()
            {
                InitializeComponent();     
            }

            private void button2_Click(object sender, EventArgs e)
            {
                panel2.Controls.Clear();
                battery bt = new battery();
                bt.TopLevel = false;           
                panel2.Controls.Add(bt);
                bt.Show();
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                string[] ports = SerialPort.GetPortNames();
                cBoxPorts.Items.AddRange(ports);
                serialPort1.DtrEnable = false;
                serialPort1.RtsEnable = false;

            }

            private void button1_Click(object sender, EventArgs e)
            {
                panel2.Controls.Clear();
                panel2.Controls.Add(panel4);
                panel2.Controls.Add(panel3);

            }



            private void button3_Click(object sender, EventArgs e)
            {
                panel2.Controls.Clear();
                Controls ct = new Controls();
                ct.TopLevel = false;
                panel2.Controls.Add(ct);
                ct.Show();
            }


            private void btn_open_Click(object sender, EventArgs e)
            {
                try
                {
                    string stopbit = "One";
                    string Paritybit = "None";
                    serialPort1.PortName = cBoxPorts.Text;
                    serialPort1.BaudRate = Convert.ToInt32(9600);
                    serialPort1.DataBits = Convert.ToInt32(8);
                    serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), stopbit);
                    serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity), Paritybit);
                    serialPort1.Open();

                }
                catch (Exception err)
                {
                    MessageBox.Show("port not connected!!!!!");
                }
            }



            private void btn_close_Click(object sender, EventArgs e)
            {
                serialPort1.Close();

            }

            private void toggleSwitch1_CheckedChanged(object sender, EventArgs e)
            {


                try
                {
                    if (toggleSwitch1.Checked == true)
                            {
                                string stopbit = "One";
                                string Paritybit = "None";
                                serialPort1.PortName = cBoxPorts.Text;
                                serialPort1.BaudRate = Convert.ToInt32(9600);
                                serialPort1.DataBits = Convert.ToInt32(8);
                                serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), stopbit);
                                serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity), Paritybit);
                                serialPort1.Open();
                            }               
                    else
                    {
                        serialPort1.Close();
                        toggleSwitch1.Checked = false;
                    }
                }
                catch (Exception err)
                {
                    MessageBox.Show("port not connected!!!!!");
                    toggleSwitch1.Checked = false;
                }



            }
        }
    }

    //Battery.cs

    using System;
    using System.Drawing;
    using System.Linq;
    using System.Windows.Forms;


    namespace DarkDemo
    {
      
        public partial class battery : Form
        {
            
           
            public  battery()
            {
                InitializeComponent();
            }

           
            private void button1_Click(object sender, EventArgs e)
            {
               
                foreach (Form1 oForm1 in Application.OpenForms.OfType<Form1>())
                {
                    oForm1.button2.ForeColor = Color.Red;
                    circularProgressBar1.ProgressColor = Color.Red;
                    circularProgressBar1.Value = 40;
                    circularProgressBar1.Text = "40";
                    oForm1.button2.Image = DarkDemo.Properties.Resources.low_battery;
                }


            }
        }
    }

                                                                                                             
    • Edited by varun_bwazz Wednesday, February 5, 2020 9:22 AM
    Wednesday, February 5, 2020 9:20 AM
  •         // Every time you use "new" you're instancing a new class with default or empty values
            // Per your description, these 3 routines are your problem.
    
            private void button1_Click(object sender, EventArgs e)
            {
                // Don't clear the panel every time.  Just make these things DOCK->FILL 
                // and then bring them to the front or send them to the back of the z-index-order 
                // as GUI events occur
                panel2.Controls.Clear();
                panel2.Controls.Add(panel4);
                panel2.Controls.Add(panel3);
    
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                // Don't clear the panel every time.  Just make these things DOCK->FILL 
                // and then bring them to the front or send them to the back of the z-index-order 
                // as GUI events occur
                panel2.Controls.Clear();
                // new means new instance with clean fields
                battery bt = new battery();
                bt.TopLevel = false;           
                panel2.Controls.Add(bt);
                bt.Show();
            }
    
    
            private void button3_Click(object sender, EventArgs e)
            {
                // Don't clear the panel every time.  Just make these things DOCK->FILL 
                // and then bring them to the front or send them to the back of the z-index-order 
                // as GUI events occur
                panel2.Controls.Clear();
                // again new means new instance with clean fields
                Controls ct = new Controls();
                ct.TopLevel = false;
                panel2.Controls.Add(ct);
                ct.Show();
            }

    Note that I added my own comments into your code quoted above, and also that the top-level controls (buttons and panel1) in my code below are added via the VS Designer, not instanced in-form like the contents of panel1 are.

    Your codeblock above contained references to lots of stuff and rather than modify it in-place and cause confusion, my codeblock below contains a simplified demonstration of how to accomplish what you say you're looking for.

        public partial class Form1 : Form
        {
            // By placing a declaration of the subform at the class-scope for Form1, that 
            // individual instance of your subform persists until Form1 closes down.
            subform0 bt = new subform0();
            subform1 ct = new subform1();
    
            Panel p3 = new Panel();
            Panel p4 = new Panel();
    
            Label p3l = new Label();
            Label p4l = new Label();
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                // Or whatever dockstyle you prefer for these panels
                this.p3.Dock = DockStyle.Top;
                this.p4.Dock = DockStyle.Bottom;
    
                p3l.Text = @"Panel 3";
                p3l.Dock = DockStyle.Top;
                p3.Controls.Add(p3l);
    
                p4l.Text = @"Panel 4";
                p4l.Dock = DockStyle.Top;
                p4.Controls.Add(p4l);
                
    
                bt.TopLevel = false;
    
                ct.TopLevel = false;
    
    
                this.panel1.Controls.Add(p3);
                this.panel1.Controls.Add(p4);
                this.panel1.Controls.Add(bt);
                this.panel1.Controls.Add(ct);
    
                // Just don't show these puppies until button clicks occur
            }
    
            // Wired up the FormClosing event via the designer
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                this.bt.Close();
                this.bt.Dispose();
    
                this.ct.Close();
                this.ct.Dispose();
    
                this.p3l.Dispose();
                this.p4l.Dispose();
    
                this.p3.Dispose();
                this.p4.Dispose();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                // On testing it appears that you can still see the edges of the "hidden behind" forms
                // and panels.  In that case you may want to go ahead and hide everything anyway.
                foreach (Control c in this.panel1.Controls)
                {
                    c.Hide();
                }
    
                this.bt.BringToFront();
                // Not really necessary since we're just putting other UI elements 
                // on top of it, but maybe necessary if users actually CLOSE the 
                // battery form, which is set to HIDE rather than allow close-by-user
                this.bt.Show();
    
                // Making batteries fill the entire display panel effectively hides everything else
                // just by bringing it to the front
                bt.WindowState = FormWindowState.Maximized;
                // With WinForms you can't make them DOCK, you have to MAXIMIZE
    
                // Forces input focus to the shown GUI element
                this.bt.Focus();
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                // On testing it appears that you can still see the edges of the "hidden behind" forms
                // and panels.  In that case you may want to go ahead and hide everything anyway.
                foreach (Control c in this.panel1.Controls)
                {
                    c.Hide();
                }
    
                this.ct.BringToFront();
               
                // Not really necessary since we're just putting other UI elements 
                // on top of it, but maybe necessary if users actually CLOSE the 
                // controls form, which is set to HIDE rather than allow close-by-user
                this.ct.Show();
    
                // Making Controls fill the entire display panel effectively hides everything else
                // just by bringing it to the front
                ct.WindowState = FormWindowState.Maximized;
                // With WinForms you can't make them DOCK, you have to MAXIMIZE
    
                // Forces input focus to the shown GUI element
                this.ct.Focus();
            }
    
            private void button3_Click(object sender, EventArgs e)
            {
                // On testing it appears that you can still see the edges of the "hidden behind" forms
                // and panels.  In that case you may want to go ahead and hide everything anyway.
                foreach (Control c in this.panel1.Controls)
                {
                    c.Hide();
                }
    
                // As long as panels 3 and 4 consume the entire container display area, 
                // this will effectively hide both the forms which are docked to FILL
                this.p3.BringToFront();
                this.p3.Show();
    
                this.p4.BringToFront();
                this.p4.Show();
    
                this.p3.Focus();
            }
        }
    
        // subform0 to emulate your battery form
        public partial class subform0 : Form
        {
            public subform0()
            {
                InitializeComponent();
            }
    
            private void subform_Load(object sender, EventArgs e)
            {
                this.Text = @"battery";
            }
    
            // Add a formclosing event to your class to modify runtime behavior
            private void subform_FormClosing(object sender, FormClosingEventArgs e)
            {
                // This should cover all UI events such as User clicked X button or 
                // User hit ALT+F4 - this leaves all system-initiated form closures 
                // as normal.
                if (e.CloseReason == CloseReason.UserClosing)
                {
                    // Hide the form instead of close
                    this.Hide();
                    // Cancel the close operation
                    e.Cancel = true;
                }
    
                // Alternately all you have to do is hide the control boxes on this form (minimize, maximize, close)
                // and maybe hide that titlebar altogether too, and then set e.Cancel to true without hiding the 
                // form at all - if other UI elements you stick in its container are properly sized/docked, then just 
                // bringing them to the front on button clicks will hide the form behind them
            }
        }
    
        // I believe that the item shown in your original example called "Controls" is also a form, 
        // just like "battery" so I'm using subform1 to represent your controls class (not shown in 
        // your example but shown in what code you did present)
        public partial class subform1 : Form
        {
            public subform1()
            {
                InitializeComponent();
            }
    
            private void subform1_Load(object sender, EventArgs e)
            {
                this.Text = @"Controls";
            }
    
    
            private void subform1_FormClosing(object sender, FormClosingEventArgs e)
            {
                // This should cover all UI events such as User clicked X button or 
                // User hit ALT+F4 - this leaves all system-initiated form closures 
                // as normal.
                if (e.CloseReason == CloseReason.UserClosing)
                {
                    // Hide the form instead of close
                    this.Hide();
                    // Cancel the close operation
                    e.Cancel = true;
                }
    
                // Alternately all you have to do is hide the control boxes on this form (minimize, maximize, close)
                // and maybe hide that titlebar altogether too, and then set e.Cancel to true without hiding the 
                // form at all - if other UI elements you stick in its container are properly sized/docked, then just 
                // bringing them to the front on button clicks will hide the form behind them
            }
        }


    Wednesday, February 5, 2020 5:28 PM
  • Hi varun_bwazz,
    Has your problem been solved? If it is resolved, we suggest that you mark it as the answer. So it can help other people who have the same problem find a solution quickly. 
    Best Regards,
    Daniel Zhang


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, March 4, 2020 7:29 AM