Link to home
Start Free TrialLog in
Avatar of IT Guy
IT Guy

asked on

C# Windows Form Navigation - Total Beginner

I have some programming experience with VB and lots of T-SQL - but this is my first venture into a C# Windows Forms project.

I need a main form and 4 forms that open and close from the main form. The method I want to use is to hold a reference to a form, as per the code below. The problem is that I have tried to add this code to my project and it won't even compile, so I'm obviously doing something very wrong.

I would like a step-by-step guide of hos to get this mechanism, i.e. where do I put this code. I am a little familiar with creating classes and forms etc, just some help in getting this to work may turn on the light for me.

http://stackoverflow.com/questions/3005732/showing-a-hidden-form

The first person who can give me specifics as to how I can implement the above mechanism in a C# Windows Form app gets the points.
Avatar of Éric Moreau
Éric Moreau
Flag of Canada image

have you considered using a MDI form with a menu?
Avatar of IT Guy
IT Guy

ASKER

I have, but I'd like only one form to be displayed at one time - this is proof of principle for me, perhaps when I get more into the app I'm writing I'll implement MDI - but not today.
You can hold a reference and call Show()/Hide() on the reference of the form easily enough; e.g. -

Form1.cs -
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Windows.Forms;

namespace EE_Q29016206
{
    public partial class Form1 : Form
    {
        readonly List<Form> ChildForms = new List<Form>();
        public Form1()
        {
            InitializeComponent();
        }

        private void OnClick(object sender, EventArgs e)
        {
            if (sender is Button)
            {
                var btn = sender as Button;
                var action = btn.Text.Split(' ');
                if (action.Length == 2)
                {
                    var form = ChildForms.Where(x => x.Name.Equals(action[1])).FirstOrDefault();
                    if (form == null)
                    {
                        switch (action[1])
                        {
                            case "Form2":
                                form = new Form2();
                                break;
                            case "Form3":
                                form = new Form3();
                                break;
                            case "Form4":
                                form = new Form4();
                                break;
                            case "Form5":
                                form = new Form5();
                                break;
                        }
                        ChildForms.Add(form);
                    }

                    switch (action[0])
                    {
                        case "Show":
                            form.Show();
                            btn.Text = string.Format("Hide {0}", form.Name);
                            break;
                        case "Hide":
                            form.Hide();
                            btn.Text = string.Format("Show {0}", form.Name);
                            break;
                    }
                }
            }
        }
    }
}

Open in new window

Form1.Designer.cs -
namespace EE_Q29016206
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.button3 = new System.Windows.Forms.Button();
            this.button4 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(13, 13);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(259, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "Show Form2";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.OnClick);
            // 
            // button2
            // 
            this.button2.Location = new System.Drawing.Point(13, 42);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(259, 23);
            this.button2.TabIndex = 1;
            this.button2.Text = "Show Form3";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.OnClick);
            // 
            // button3
            // 
            this.button3.Location = new System.Drawing.Point(13, 71);
            this.button3.Name = "button3";
            this.button3.Size = new System.Drawing.Size(259, 23);
            this.button3.TabIndex = 2;
            this.button3.Text = "Show Form4";
            this.button3.UseVisualStyleBackColor = true;
            this.button3.Click += new System.EventHandler(this.OnClick);
            // 
            // button4
            // 
            this.button4.Location = new System.Drawing.Point(13, 100);
            this.button4.Name = "button4";
            this.button4.Size = new System.Drawing.Size(259, 23);
            this.button4.TabIndex = 3;
            this.button4.Text = "Show Form5";
            this.button4.UseVisualStyleBackColor = true;
            this.button4.Click += new System.EventHandler(this.OnClick);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(284, 129);
            this.Controls.Add(this.button4);
            this.Controls.Add(this.button3);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.Button button3;
        private System.Windows.Forms.Button button4;
    }
}

Open in new window

Form2.cs -
using System;
using System.Windows.Forms;

namespace EE_Q29016206
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void OnLoad(object sender, EventArgs e)
        {
            label1.Text = string.Format(label1.Text, Name);
        }
    }
}

Open in new window

Form2.Designer.cs -
namespace EE_Q29016206
{
    partial class Form2
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.label1 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label1.Location = new System.Drawing.Point(0, 0);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(133, 20);
            this.label1.TabIndex = 1;
            this.label1.Text = "This is form {0}.";
            // 
            // Form2
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(284, 106);
            this.Controls.Add(this.label1);
            this.Name = "Form2";
            this.Text = "Form2";
            this.Load += new System.EventHandler(this.OnLoad);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Label label1;
    }
}

Open in new window

(rinse and repeat Fomr2 for Form3, Form4 and Form5)...

Produces the following output -
Initial load -User generated imagePressing on the button shows the related form -User generated imagePressing on the hide button hides the related form.

Caveats -
Becomes harder to manage as you add more controls/forms.  At that point probably makes more sense to either rethink your design or use attribute/helper class driven logic.
Not dialoged, so parent can be accessed at any time.
If a child is closed it is not removed from the collection and the parent form does not visually indicate that the child has closed.

-saige-
Avatar of IT Guy

ASKER

Saige.

That is awesome, obviously you get the points.

....but how would I put a button on form 2 to close form 2? I may need to reopen and close each form more than once.
That all depends on what you want the state of Form2 to be when it is closed.

- Do you want Form2 to be disposed or just hidden?
- If you want it to be closed then why hold a reference of it at all.
- If you want it to be hidden then you have to change the functionality of the form from it's closing event (to prevent closing and disposing of the form) as well has trigger an event so that Form1 will update accordingly.

-saige-
Avatar of IT Guy

ASKER

I want Form2 (or Form3 or Form4) to only be hidden - I understand that C# doesn't like reopening a form it has already disposed of, so we'll hide it.

And then when we close the app we'll check for the state of all forms and close them before closing the main form. Also, from what I understand, we don't need to worry about threading when dealing with forms.
Avatar of IT Guy

ASKER

And, you're an expert. The following words sound easy, but without an example they're not easy for me at the moment:

- If you want it to be hidden then you have to change the functionality of the form from it's closing event (to prevent closing and disposing of the form) as well has trigger an event so that Form1 will update accordingly.

I would love to see this incorporated in your code.
ASKER CERTIFIED SOLUTION
Avatar of it_saige
it_saige
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of IT Guy

ASKER

Fantastic. This guy knows their stuff and I'm very grateful for his/her assistance.