A common pattern in form design is the wizard pattern. You probably are familiar with the way that wizards work. When you start the wizard, you progress from page to page by using Next and Previous buttons. On the final page, you can complete the wizard by clicking Finish. You'll almost always have the option of canceling the wizard. Sometimes you are allowed to jump from screen to screen by using a menu on the side, but often the developer needs to ensure that the user steps through screen 1 before going to screen 2, and so on in a linear fashion.
Developers using earlier versions of ASP.NET resorted to using panel controls to create individual areas of a page that could be made visible and invisible as needed. Fortunately, ASP.NET 2.0 provides a new Wizard control to streamline development of wizard Web Forms.
To show the power of the Wizard control, I created a new Web page in the WebPageLayout project, named WizardForm.aspx. After dragging and dropping a Wizard control onto the form, the Wizard Tasks smart tag appeared, as shown in Figure 3-31.
Figure 3-31: The Wizard control and the Wizard Tasks smart tag
The first task when creating a wizard Web Form is usually to add and remove wizard steps. The WizardStep Collection Editor dialog box is shown in Figure 3-32.
Figure 3-32: The WizardStep Collection Editor dialog box
For this example, I wanted four steps:
Enter text in a text box
Select from drop-down list
Select or clear a check box
Finish
I clicked Add until I had four steps, and then I changed the names. The resulting WizardStep Collection Editor dialog box appears in Figure 3-33.
Figure 3-33: The WizardStep Collection Editor dialog box with four steps defined
In the WizardStep Collection Editor dialog box, you can change the order of the steps and force the wizard step to be a particular StepType. The possible types are:
Auto Allows the Wizard control to determine what type of step this is. There is almost never a need to change from this default.
Complete A complete step, with no buttons.
Finish A step with the Next button rendered as a Finish button. No Previous button is rendered.
Start The first step to appear, with a Next button but no Previous button.
Step A step between the Start and Finish steps.
After the four steps are entered, the markup in the WizardForm.aspx file appears as shown in Listing 3-8.
Listing 3-8: WizardForm.aspx with Steps Added
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="WizardForm.aspx.cs" Inherits= "WizardForm" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Untitled Page</title> </head> <body> <form runat="server"> <div> <asp:Wizard runat="server"> <WizardSteps> <asp:WizardStep runat="server" Title="Enter Text in Text Box"> </asp:WizardStep> <asp:WizardStep runat="server" Title="Select From DropDownList"> </asp:WizardStep> <asp:WizardStep runat="server" Title="Checking or Unchecking CheckBox"> </asp:WizardStep> <asp:WizardStep runat="server" Title="Finish"> </asp:WizardStep> </WizardSteps> </asp:Wizard> </div> </form> </body> </html>
If you look back at Figure 3-31, you will see that the smart tag menu includes an Auto Format option. The Auto Format dialog box allows you to look at the various format settings by clicking the format name in the list of schemes on the left. Figure 3-34 shows one format that I like.
Figure 3-34: The Auto Format dialog box showing one of the Auto Format settings
If you click OK, the format is applied to your Wizard control. Because of the screen constraints and the verbosity of the step names, you should hide the side bar. With focus on the Wizard control in Design view, you can disable the side bar in the Properties window by setting the DisplaySideBar property to False. To make the Wizard control easier to work with, you can click and drag the lower right corner. The control changes color and the size appears as you drag the corner, as shown in Figure 3-35.
Figure 3-35: Resizing the Wizard control in Visual Studio
Now you can drag and drop controls onto the form. For Step 1, drag two Label controls (each on a separate line) and a TextBox control, and set the label text and TextBox name as shown in the Properties window. In the first Label control, enter "Step 1" as the text, and in the second Label control, enter "Your Dog's name is:". When running, WizardForm.aspx appears for Step 1 as shown in Figure 3-36.
Figure 3-36: WizardForm.aspx on Step 1
Look back at Figure 3-31, and notice the drop-down list with the names of the steps. Selecting a different step in this list allows you to design that step. For Step 2, perform the same tasks described previously, but in the "Select from drop-down list" step, add two labels and a drop-down list control with Red, Green, and Blue list items. The first Label control should have the text "Step 2", and the second should have "Your Favorite Color:" for the text. When running, Step 2 appears in WizardForm.aspx as shown in Figure 3-37.
Figure 3-37: WizardForm.aspx on Step 2
For Step 3, add a Label control to the "Select or clear a check box" screen with "Step 3" as the text, and on the next line drag and drop a check box with "I am allergic to cats" as the text. WizardForm.aspx appears when it is run for Step 3 as shown in Figure 3-38.
Figure 3-38: WizardForm.aspx on Step 3
For the final page, Step 4, add two labels. The first Label control should have "Step 4" as its text, and the second Label control should have no text and should be named "FinishLabel" because this Label control will be accessed from code. Step 4 appears in WizardForm.aspx as shown in Figure 3-39.
Figure 3-39: WizardForm.aspx on Step 4
In the end, the markup for the page should be similar to Listing 3-9.
Listing 3-9: WizardForm.aspx with Controls Added to Steps
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="WizardForm.aspx.cs" Inherits="WizardForm" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Untitled Page</title> </head> <body> <form runat="server"> <div> <asp:Wizard runat="server" ActiveStepIndex="0" BackColor="#EFF3FB" BorderColor="#B5C7DE" BorderWidth="1px" DisplaySideBar="False" Font-Names="Verdana" Font-Size="0.8em" Height="265px" Width="406px"> <WizardSteps> <asp:WizardStep runat="server" Title="Enter Text in Text Box"> <asp:Label runat="server" Text="Step 1"> </asp:Label> <br /> <asp:Label runat="server" Text="Your Dog's Name is:"> </asp:Label> <asp:TextBox runat="server"></asp:TextBox> </asp:WizardStep> <asp:WizardStep runat="server" Title="Select From DropDownList"> <asp:Label runat="server" Text="Step 2"> </asp:Label> <br /> <asp:Label runat="server" Text="Your Favorite Color:"> </asp:Label> <asp:DropDownList runat="server"> <asp:ListItem>Red</asp:ListItem> <asp:ListItem>Green</asp:ListItem> <asp:ListItem>Blue</asp:ListItem> </asp:DropDownList> </asp:WizardStep> <asp:WizardStep runat="server" Title="Checking or Unchecking CheckBox"> <asp:Label runat="server" Text="Step 3"> </asp:Label> <br /> <asp:CheckBox runat="server" Text= "I am allergic to cats" /> </asp:WizardStep> <asp:WizardStep runat="server" Title="Finish"> <asp:Label runat="server" Text="Step 4"> </asp:Label> <br /> <asp:Label runat="server"></asp:Label> </asp:WizardStep> </WizardSteps> <StepStyle Font-Size="0.8em" ForeColor="#333333" /> <SideBarStyle BackColor="#507CD1" Font-Size="0.9em" VerticalAlign="Top" /> <SideBarButtonStyle BackColor="#507CD1" Font-Names="Verdana" ForeColor="White" /> <HeaderStyle BackColor="#284E98" BorderColor="#EFF3FB" BorderStyle="Solid" BorderWidth="2px" Font-Bold="True" Font-Size="0.9em" ForeColor="White" HorizontalAlign="Center" /> <NavigationButtonStyle BackColor="White" BorderColor="#507CD1" BorderStyle="Solid" BorderWidth="1px" Font-Names="Verdana" Font-Size="0.8em" ForeColor="#284E98" /> </asp:Wizard> </div> </form> </body> </html>
In addition to the controls that were manually added to the form, several tags related to the Auto Format settings appear toward the bottom of the markup. On the last page, I renamed the second label from the default to "FinishLabel" to make it easier to identify.
After setting the look of the wizard, the next step is to add code that does something with the entered information. In many cases, this involves adding data to a database. In this example, however, I simply summarize the entered information.
Before I perform this summarization, you should be aware of several helpful Wizard control properties and events. Table 3-2 summarizes the most important of them.
Member Name | Description |
---|---|
ActiveStep | A property that gets the step in the WizardSteps collection that is currently displayed to the user. |
ActiveStepIndex | A property that gets or sets the index of the current step. |
FinishDestinationPageUrl | A property that gets or sets the URL that the user is redirected to when the Finish button is clicked. |
WizardSteps | A property that sets a collection of WizardStepBase objects defined in the control. |
ActiveStepChanged | An event that occurs when the user switches to a new step in the control. |
CancelButtonClick | An event that occurs when the Cancel button is clicked. |
FinishButtonClick | An event that occurs when the Finish button is clicked. |
NextButtonClick | An event that occurs when the Next button is clicked. |
PreviousButtonClick | An event that occurs when the Previous button is clicked. |
SideBarButtonClick | An event that occurs when a button on the side bar is clicked. |
The ActiveStepChanged event is the most important of the events. You will often need to perform some action when active steps are changed. Although it might be tempting to use one of the button click events to perform some action, it is almost always not the best way to handle the change of the screen. The most significant problem is that handling a button click does not address all the possible ways in which a step can be reached. A step can be reached by clicking Next or Previous, or possibly even by clicking one of the side bar menus, if they are present.
When the ActiveStepChanged event handler is called, you can determine which step is active in a couple of ways. You can look at the ActiveStepIndex property, or you can check some property (such as the Name property) of the ActiveStep property.
In this example, I want to summarize the selections made in the wizard. To create an event handler, click the Wizard control in the Visual Studio Design view, and then in the Properties window, click the Event button (which looks like a lightning bolt) to see a list of events. The Event button is shown in Figure 3-40.
Figure 3-40: Event button in the Properties window
Double-clicking the area to the right of the ActiveStepChanged event name in the Properties window opens the code file inside an event handler. To set the text of the FinishLabel control, I added the following code.
protected void Wizard1_ActiveStepChanged(object sender, EventArgs e) { if (this.Wizard1.ActiveStepIndex == 3) { this.FinishLabel.Text = "Your Dog's Name is " + this.DogName.Text + "<br />"; this.FinishLabel.Text += "Your favorite color is " + this.DropDownList1.SelectedItem.Text + "<br />"; if ( this.CheckBox1.Checked==true) { this.FinishLabel.Text += "And you are allergic to cats."; } else { this.FinishLabel.Text += "And you are <b>not</b> allergic to cats."; } } }
This code checks the ActiveStepIndex property of the Wizard1 control, looking for an ActiveStepIndex of 3.
Note | In some cases, you'll want to use the OnFinish event that is fired when the Finish button is clicked to handle the end of a Wizard operation. In this case, I wanted to display something special as the Finish step starts, so I used the ActiveStepChanged event and checked the index of the step. |
When you run the page and step through the wizard, the last step will look something like the screen shown earlier in Figure 3-39.
Of course, the details will vary depending on the user's pet history and color preferences. The neat thing about the Wizard control is that the properties of all controls anywhere in the wizard are available in every step, even when the controls in question are not visible to the user.
Note that my earlier advice about using the button click events does not apply to the Finish button event handler. You will often want to perform specific actions when the user has indicated that he or she is finished with the wizard.