Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Creating a wizard layout using C#

0.00/5 (No votes)
26 Jun 2016 1  
An article to create a wizard layout using C# Windows Forms Application

Introduction

We might have seen a lot of wizards which we come across, with Back, Next, Cancel Buttons. It tends to be tedious if we design seperate forms for each of the wizard step with a seperate copy of buttons in each form. Hence I decided to create a basic template (parent form) that will load a form (of the wizard step) based on the user's click on Back or Next Buttons. An added advantage in the layout is that, the back and next buttons become disabled automatically, based on the form that is loaded.

Using the code

Let me tell you about some variables that I'll be using to change the forms.

Variable Purpose
int top The index of the current form that is in use.
int count The total count of forms, which we are going to use in the wizard.
Form[] frm The array collection of forms used in the wizard

Let us assume the case of a stack. A stack has a top variable that corresponds to the current element of the stack. The top variable is kept changing based on the event. (i.e.) it is increased for the next element (Next) and decreased for the previous element (Back).

Let us assume that the stack takes up a value, top = -1 to show that there are no more forms that can be moved back (underflow condition). If top = count then there are no more forms that can be moved next (overflow condition). We will be implementing the same concept, but we'll be working with forms.

Follow the following steps,

Designing the Parent Form

  • Create a new Windows Forms project.
  • Add a form. Name this as frmParent. This will be our parent (host) form.
  • Add three panels (based on your content) to the form and name them, pnlLeft, pnlContent, pnlNavigation and set their dock properties to Left, Fill, Bottom (respectively).
  • We will be using pnlLeft to display the logo, pnlContent to change the forms and pnlNavigation for the navigation buttons.

Now the layout of the Parent Form should look like this,

  • Use appropriate controls to design the basic layout of the form. I have used a picture box to display the logo of the wizard. I've added a TableLayoutPanel in the pnlNavigation, that holds the three buttons (namely Back, Next and Cancel).
  • Add the buttons, and name them btnBack, btnNext, btnCancel.
  • I've added required padding to achieve the look and feel. You may try this based on your layout design.

The output would be similar to,

Sample Layout Design

Designing the Child Forms

You can create as many as child forms as much as you want in the wizard. But make sure that every child form that you design have the following properties,

Property Value
FormBorderStyle None
AutoScroll True
   

Design the child forms based on your requirement, from the starting form to the ending form. For this demonstration, I am designing three forms, namely frm1, frm2, frm3. In this case frm1 will act as the first form and frm3 acts as the final form.

I've attached a sample of the first form (frm1) in here. The FormBorderStyle has been set to none and the AutoScroll Property has been turned on. I've also applied necessary padding, and tweaked other properties to get the look of the form.

Sample Child Form Design

Coding

Initially, I'll have to initialize the Form array with the forms I am going to use in the wizard. The code must be placed in the parent form before the constructor.

Form[] frm = { new frm1(), new frm2(), new frm3() };
int top = -1;
int count;

Now in the constructor of the parent form, we have to initialize the count variable.

public frmParent()
        {
            count = frm.Count();
            InitializeComponent();
        }

I'm creating a function that will load a currently set form into the panel (pnlContent) of the main form. I'll call it LoadNewForm(). This function will be called thrice,

  1. During the loading of the parent form (first time, first form must be shown)
  2. During the click of the Back Button (previous form must be loaded)
  3. During the click of the Next Button (next form must be loaded).

It will look similar to this,

frm[top].TopLevel = false;
frm[top].Dock = DockStyle.Fill;
this.pnlContent.Controls.Clear();
this.pnlContent.Controls.Add(frm[top]);
frm[top].Show();

The function, makes the child form, to act as a child form (using TopLevel property), fills the form as a content in the panel of the Parent Form (using DockStyle.Fill), clears all content in the panel for fresh loading of the form (pnlContent.Controls.Clear()), adds the current form (top) into the panel and displays the form in the panel.

To understand this piece of code, you can refer to this question posted in Codeproject, http://www.codeproject.com/Questions/414107/Csharp-Form-inside-a-Panel

Moving to the next form

The following must happen if the next button is clicked,

  • The variable top must be incremented.
  • If value of top exceeds or equals, the total count of forms, then do nothing (return).
  • Otherwise, Load the current form into the panel and check if the current form is the last form of the list. If yes, then disable the next button.
  • If there is no more forms available (i.e. top == -1) then disable the Back button.

The code will look like,

private void Next()
       {

           top++;
           if (top >= count)
           {
               return;
           }
           else
           {
               btnBack.Enabled = true;
               btnNext.Enabled = true;
               LoadNewForm();
               if (top + 1 == count)
               {
                   btnNext.Enabled = false;
               }
           }

           if (top <= 0)
           {
               btnBack.Enabled = false;
           }
       }

Call Next() during the Form Load and as well as when the next button is clicked.

Moving to the previous form

Moving to the previous form is the exact opposite of Moving to the next form. Hence the code will be as follows,

private void Back()
{
    top--;

    if (top <= -1)
    {
        return;
    }
    else
    {
        btnBack.Enabled = true;
        btnNext.Enabled = true;
        LoadNewForm();
        if (top - 1 <= -1)
        {
            btnBack.Enabled = false;
        }
    }

    if (top >= count)
    {
        btnNext.Enabled = false;
    }
}

Call Back() when back button is clicked.

Voila. That's it. The entire code will look like,

public partial class frmParent : Form
   {
       Form[] frm = { new frm1(), new frm2(), new frm3(), new frm4(),
                    new frm5()};
       int top = -1;
       int count = 5;
       public frmParent()
       {
           InitializeComponent();
       }

       private void LoadForm()
       {
           frm[top].TopLevel = false;
           frm[top].AutoScroll = true;
           frm[top].Dock = DockStyle.Fill;
           this.pnlContent.Controls.Clear();
           this.pnlContent.Controls.Add(frm[top]);
           frm[top].Show();
       }

       private void Back()
       {
           top--;

           if(top <= -1)
           {
               return;
           }
           else
           {
               btnBack.Enabled = true;
               btnNext.Enabled = true;
               LoadForm();
               if (top - 1 <= -1)
               {
                   btnBack.Enabled = false;
               }
           }

           if(top>=count)
           {
               btnNext.Enabled = false;
           }
       }
       private void Next()
       {

           top++;
           if (top >= count)
           {
               return;
           }
           else
           {
               btnBack.Enabled = true;
               btnNext.Enabled = true;
               LoadForm();
               if(top+1 == count)
               {
                   btnNext.Enabled = false;
               }
           }

           if (top <= 0)
           {
               btnBack.Enabled = false;
           }
       }

       private void frmParent_Load(object sender, EventArgs e)
       {
           Next();
       }

       private void btnNext_Click(object sender, EventArgs e)
       {
           Next();
       }

       private void btnBack_Click(object sender, EventArgs e)
       {
           Back();
       }
   }

I've applied Docking for certain components. So they can adapt even if you resize the application, or maximize it. The cancel button can also be renamed to "Finish" Button depending on the flavour of the design.

History

Version 1 : Current Version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here