Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Using the ASP.NET 2.0 Wizard Control

3.88/5 (12 votes)
1 Sep 20062 min read 1  
How to dynamically create an ASP.NET 2.0 Wizard control and load child controls at run-time.

Introduction

This article demonstrates how to load controls and attach event handlers inside an ASP.NET 2.0 Wizard control at run-time. The demo is a simple quiz program that prompts users to enter how many questions they would like to load into the Wizard control. The number of questions entered determines the WizardSteps to create at run-time and how many set of controls to create for the Wizard control.

The demo will display an Image control that displays a flag, followed by a RadioButtonList with three choices for the user to select. When a user clicks on the Finish button, the program calculates the total correct answers. The demo is developed using ASP.NET 2.0 with data stored in a SQL Server 2005 table.

Fig. 1 below prompts the user for the number of questions to load in the Wizard control.

Image 1

Fig. 2 below shows the wizard loaded with five questions. Each question (i.e., a WizardStep) is loaded with an Image control and a RadioButtonList with pre-defined choices. The image and RadioButtonList choices are stored in a SQL Server table.

Image 2

The user makes the proper selection in the RadioButtonList and clicks the Next button to move onto the next WizardStep. The user can also click on the SideBar and navigate to other WizardSteps in a non-sequential manner.

Fig. 3 below shows how when the Finish button is clicked, a score is calculated by looping through prior user selections in the Wizard control.

Image 3

Easy enough….now let’s talk about the code behind these screens. Fig. 1 prompts users for an input, and uses a Server.Transfer() to move to the screen in Fig. 2. In the design screen of Fig. 2, only a PlaceHolder control and a Label control are needed. The PlaceHolder control is used to host the Wizard control created at run-time. The Label control is used to display the calculated score. The following code is implemented in the Page_Load event of Fig. 2.

C#
using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Microsoft.ApplicationBlocks.Data;
using System.ComponentModel;

public partial class TestWizardControl1 : System.Web.UI.Page
{
    string thisConnectionString = 
      ConfigurationManager.ConnectionStrings[
      "PracticeDataConnectionString"].ConnectionString;
    System.Data.DataSet thisDataSet = new System.Data.DataSet();

    protected void Page_Load(object sender, EventArgs e)
    {       
        Wizard WizardControl = new Wizard();
        WizardControl.Height = Unit.Pixel(150);
        WizardControl.Width = Unit.Pixel(200);
        WizardControl.Style["Top"] = "111px";
        WizardControl.Style["Left"] = "333px";
        WizardControl.Style["Position"] = "absolute";

        // The demo uses a Session Variable titled "HowManySteps"
        // collected from Fig. 1 to determine the size 
        // of the Wizard control at run-time. The Wizard Control has an
        // initial index of 0. Therefore, subtracting 1 from
        // the session variable is needed.

        int j = Convert.ToInt16(Session["HowManySteps"]) - 1;
        for (int i = 0; i <= j; i++)
        {
            WizardStepBase newStep = new WizardStep();
            newStep.ID = "Step" + (i + 1).ToString();
            WizardControl.WizardSteps.Add(newStep);
        }

        //Dynamically attach an EventHandler to calculate 
        //final score to the FINISH Button

        WizardControl.FinishButtonClick += new 
          WizardNavigationEventHandler(WizardControl_FinishButtonClick);
        PlaceHolder1.Controls.Add(WizardControl);

        //Create your own ad hoc query or a stored procedure 
        //to retrieve the image for the Image Control 
        //and the choices for the RadioButtonList Control. 
        //The ExecuteDataset method from the Microsoft 
        //Application Block is used here to call a 
        //stored procedure name "Wizard_Retrieve".

        thisDataSet = SqlHelper.ExecuteDataset(
              thisConnectionString, "Wizard_Retrieve");
        for (int i = 0; i < WizardControl.WizardSteps.Count; i++)
        {

            //Use a variable (ex. A in the code below) 
            //to tabulate the Image Control and 
            //RadioButtonList Control for each WizardStep.
            //For example, WizardStep1 will
            //contain Image1 and RadioButtonList1.
            //WizardStep2 will contain Image2 and
            //RadioButtonList2 and so on.

            int A = i + 1;
            Image ImageControl = new Image();
            ImageControl.ID = "Image" + A.ToString();
            ImageControl.Width = Unit.Pixel(120);
            ImageControl.Height = Unit.Pixel(75);
            WizardControl.WizardSteps[i].Controls.Add(ImageControl);
            Image IMG = (Image)
              WizardControl.WizardSteps[i].FindControl("Image" + A.ToString());
            IMG.ImageUrl = thisDataSet.Tables[0].Rows[i][0].ToString().Trim();

            RadioButtonList RadioButtonListControl = new RadioButtonList();
            RadioButtonListControl.ID = "RadioButtonList" + A.ToString();
            WizardControl.WizardSteps[i].Controls.Add(RadioButtonListControl);
            RadioButtonList RBL = (RadioButtonList) 
              WizardControl.WizardSteps[i].FindControl(
              "RadioButtonList" + A.ToString());
            RBL.Width = Unit.Pixel(180);
            RBL.Height = Unit.Pixel(100);
            RBL.Items.Clear(); 

            //Use another loop to load the RadioButtonList 
            //options for each WizardStep
               
            for (int x = 1; x < 4; x++)
            {
                RBL = (RadioButtonList)
                  WizardControl.WizardSteps[i].FindControl(
                  "RadioButtonList" + A.ToString());
                RBL.Items.Add(new ListItem(
                  thisDataSet.Tables[0].Rows[i][x].ToString().Trim()));
            }                
            RBL.SelectedIndexChanged += new EventHandler(RBL_SelectedIndexChanged);
        }
    }

    //Create a EventHandler to process the 
    //SelectedIndexChanged event for the 
    //RadioButtonList in each WizardStep. 
    //Use a HiddenField Control to store the 
    //selected answer. Concatenate all answers into 
    //a single string. Parse the answer 
    //during the FINISH Button Click event to calculate final score.

    public void RBL_SelectedIndexChanged(object sender, EventArgs e)
    {
        RadioButtonList RBL = (RadioButtonList)sender;
        if (HiddenField1.Value != string.Empty)
        {
            HiddenField1.Value = HiddenField1.Value.ToString() + 
                                 "/" + RBL.SelectedValue.ToString();
        }
        else
        {
            //bypass initial delimiter "/" 
            HiddenField1.Value = RBL.SelectedValue.ToString();
        }        
    }

    public void WizardControl_FinishButtonClick(object sender, EventArgs e)
    {
        Wizard WZ=(Wizard)sender;
        char[] DelimiterChar = { '/' };
        string[] Answer = HiddenField1.Value.Split(DelimiterChar);

        thisDataSet = SqlHelper.ExecuteDataset(thisConnectionString, 
                                               "Wizard_Retrieve");
        int score = 0;
        for (int i = 0; i < WZ.WizardSteps.Count; i++)
        {
            if (thisDataSet.Tables[0].Rows[i][4].ToString().Trim() 
                                               == Answer[i].Trim())
            {
                score = score + 1;
            }
        }
        lblMessage.Text = "Your score is " + score.ToString() + 
                          " out of a total of " + 
                          (WZ.WizardSteps.Count).ToString();
    }
}

In short, this is just a simple demo to show a way of using the Wizard control. You will have to download the flags from the web (the CIA World Fact Book is a good source for flags), or you can type in your own quiz questions to make the demo an online survey or an online test. To further improve the above demo, you can implement the Page.RegisterHiddenField() method, along with the IPostBackDataHandler interface, and call the Page.RegisterRequiresPostBack() to show the selections in previous WizardSteps when the web page that hosts the control is posted back to the web server. Also, flag images or text questions and the RadioButtonList options can all be packaged into a resource file instead of retrieving them as records from a SQL Server table.

In the meantime, hope you enjoy the article and find the example above useful and adaptable in your programming scenario. Thanks!

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