LANGUAGES: VB.NET | C#
ASP.NET VERSIONS: 2.x
A Guide to the ASP.NET 2.0 Wizard Control
Simplify the Process of Gathering Information from Users
By Steve C. Orr
Creating a wizard in ASP.NET 1.x had the potential to be a bit tricky. The first thought would likely be to put each wizard step on its own page. However, this has many drawbacks, such as code (and user interface) duplication and maintaining state between each page. Therefore, most Web developers tended to lean toward keeping each wizard step in its own panel within a single page. Each panel is shown and hidden in succession, with only the panel representing the current step being visible at any one time. Because the page posts back to itself between each step, all data is kept in ViewState automatically by ASP.NET, negating the need to manually store user-entered values between each wizard step.
Of course, this technique had some downsides, too, such as needing to manage all those different panels at design time. Although not difficult, it certainly makes the design-time appearance of a page much different than the run-time appearance, as all the panels are visible at once at design time. It also required managing many redundant Back and Next buttons for each step of the wizard.
Because this technique usually turned out to be the best way to create wizards (despite its potentially hefty ViewState consumption for large wizards), the ASP.NET 2.0 team decided to polish up the process by creating a control that automates and simplifies this style of wizard creation. The ASP.NET 2.0 Wizard control shown in Figure 1 is the result.
Figure 1: The powerful Wizard control is a quick and easy way to put together a user-friendly data collection system.
The Wizard control is extremely flexible and configurable. For example, the Wizard control has more than 200 properties that can be set at design time! In addition, the Auto Format dialog box shown in Figure 2 is a quick way to beautify an otherwise boring wizard.
Figure 2: The Wizard control is highly configurable, including this Auto Format dialog box that can beautify its output in a snap.
Figure 3 shows the four main areas of the Wizard control that are ripe for customization. The header area (shown at the top of the control) is invisible by default unless (and until) the HeaderText property is set. The header text stays statically displayed on every step of the wizard, although there are options for manually changing it via code from step to step in case you have the need. The HeaderStyle can be changed in the properties window (or via HTML view) to adjust colors, fonts, alignment, etc.
Figure 3: These are the four primary areas of the Wizard control that can be customized.
The Sidebar area (shown in green at the left side of Figure 3) is normally managed entirely by the Wizard control. It contains a hyperlink list of the Wizard steps so users can jump around freely. If this behavior is not desired, the DisplaySideBar property can be set to False, or the area can be changed to a template (via a right-click menu) so the developer can take more manual control of the area. The SideBarStyle property group can be used to change colors, fonts, and other cosmetic aspects of the sidebar.
The Navigation area (shown in grey at the bottom of Figure 3) contains the Back and Next buttons that users have come to expect from wizards. Each button click causes the Web form to be posted back to the server so the information can be saved to ViewState and the next wizard step can be displayed. (Tip: To avoid ugly postbacks, the Wizard control works great inside the UpdatePanel control from the ASP.NET 2.0 AJAX Extensions, formerly codenamed Atlas.) The text of these buttons can be configured via the StepNextButtonText and StepPreviousButtonText properties. Additionally, the buttons can be configured to display as hyperlinks or custom images instead of buttons by means of the StepNextButtonType and StepPreviousButtonType properties. A Cancel button can also be optionally displayed by setting the DisplayCancelButton property to True. When the user clicks the Cancel button, they are automatically taken to the URL contained in the CancelDestinationPageUrl property. By default, the Back button is not displayed on the first step of the wizard, and the Next button is not displayed on the final step of the wizard, although these details of the wizard steps can be configured in the WizardStep Collection Editor (shown in Figure 4).
Figure 4: The WizardStep Collection Editor can be used to add and configure properties for each step of a wizard.
The Step area is the main content section that contains the custom content for the wizard. After dragging the Wizard control onto a WebForm in an ASP.NET Web application, you can immediately start customizing it by adding standard ASP.NET controls into the Step area. This area acts a lot like a panel, allowing controls to be dragged and dropped from the Visual Studio toolbox. By default, this is the only area of the Wizard control onto which controls may be dropped. However, if you have the need to customize other areas of the control, this can easily be done by converting one or more control parts to a template via the smart tag menu shown in Figure 1.
Dragging the controls into the Step area is simple enough for Step 1 of the wizard because it is the one step that s visible by default at design time. But what about for the following steps? You can adjust which step is currently visible (and editable) at design time via the Step dropdown list in the Wizard s smart tag menu (again, see Figure 1). When you run the project, the step you were last editing in the designer will be the first step to appear at run time. Although this feature is a nice time saver during development, it necessitates resetting the designer to Step 1 before deployment; otherwise, the users could end up starting on the wrong step.
To add more steps (beyond the default two steps), click the associated link in the smart tag menu (or click the associated WizardSteps ellipsis button in the Properties window) to bring up the WizardStep Collection Editor shown in Figure 4. In this dialog box the title can be set that appears for each wizard step. There you can also specify whether the user is allowed to return to that wizard step after completing it.
The StepType property can also be set from the WizardStep Collection Editor. By default, the StepType property is set to Auto, which should be suitable for most situations as it automatically determines which buttons should be visible based on the step s position in the list. However, to take more manual control you could choose one of the StepType s other enumerations, such as Start (which causes the Back button to be suppressed) or Finish (which causes only the Back and Finish buttons to be displayed). The Complete StepType enumeration setting hides the sidebar and navigation buttons, leaving a completely blank space ready for customization.
In addition to the drag and drop simplicity of the Visual Studio designer, HTML view also provides an interesting way to examine and configure the contents of the Wizard control. Everything that can be configured in design view can also be configured via HTML view, although the syntax can be rather complex, as demonstrated by the basic two-step wizard shown in Figure 5.
BackColor="#E6E2D8" BorderColor="#999999" BorderStyle="Solid" Height="251px"
Width="357px"> BorderStyle="Solid" BorderWidth="2px" /> VerticalAlign="Top" /> BorderWidth="1px" Font-Names="Verdana"
Font-Size="0.8em"/> Step 1! Step 2! BorderStyle="Solid" BorderWidth="2px"
Font-Bold="True" Font-Size="0.9em" ForeColor="White" HorizontalAlign="Center" />
BorderStyle="Solid" Height="251px" Width="357px">
BorderStyle="Solid" BorderWidth="2px" />
BorderWidth="1px" Font-Names="Verdana" Font-Size="0.8em"/>
BorderStyle="Solid" BorderWidth="2px" Font-Bold="True"
Figure 5: The Wizard control can be manipulated in HTML view, although the syntax can get rather complex, even for a basic example such as this.
As you can see, the styles for each section can be configured via HTML view, and each individual wizard step can also be independently configured.
It s convenient when wizards can be nice and simple, allowing users to jump arbitrarily between steps as they please. However, in reality, business rules often dictate that a wizard must be more complex than that. Sometimes the next wizard step must be chosen based on the selection a user made in previous wizard steps. In some cases, perhaps Step 6 should be skipped because of a selection the user made in Step 4, or perhaps the contents of Step 7 must be modified based on a selection the user made in Step 3. Luckily, the Wizard control is flexible enough to support such scenarios if you re not afraid to get your hands dirty with a little code.
The ActiveStepChanged event is convenient for intercepting transitions between wizard steps so intelligent decisions can be made based on state. For example, from within this event the wizard s ActiveStep property can be changed programmatically at your whim, or controls can be shown or hidden as required. Additionally, the GetHistory method of the Wizard control can be called to retrieve a history of the steps the user has visited. This can be quite useful for ensuring users have visited prerequisite steps.
For more granular control over step transition you might choose to handle the NextButtonClick or PreviousButtonClick events. These events have parameters such as CurrentStepIndex, NextStepIndex, and PreviousStepIndex, which help to determine where the user is going and where they have been. Similarly, the SideBarButtonClick event can be valuable for intercepting the user s attempt to skip to non-contiguous steps.
Alternatively, the FinishButtonClick event could be used for validating that the user has correctly completed steps, for displaying final instructions, and/or redirecting the user to a new page. It can also be a great place to store the user s finalized input into a database. Finally, the CancelButtonClick event can be a handy way to manage the user s desire to cancel out of a wizard.
While the above events can be great places to inject complex validation code, more often ASP.NET s built-in validation controls are sufficient. Thankfully, they interact quite well with the Wizard control. Figure 6 shows how the Wizard control can automatically enforce validation with zero lines of code in conjunction with the ASP.NET validation controls.
Figure 6: ASP.NET s validation controls play well with the Wizard control, making it a snap to ensure users have entered quality data.
In this case each of the two textboxes have validation controls associated with them. The Name textbox has a RequiredFieldValidator control associated with it to ensure the user cannot advance to the next step until a value has been entered. The Email textbox has an associated RegularExpressionValidator control ensuring that only syntactically valid e-mail addresses are entered. The error messages (shown in red) do not appear unless the user tries to leave that wizard step while invalid data is present.
For more information about the ASP.NET validation controls, see Validate User-entered Data.
Wizards have been a common user interface theme for years, and they ve stood the test of time as a useful and user-friendly input mechanism. Although they could be implemented in ASP.NET 1.x, it was not a trivial task. State management and user interface reusability presented challenges that tended to make a developer think twice before embarking on such a course.
When the ASP.NET 2.0 Wizard control came along, it vastly simplified the entire process. Developers no longer have to deal with awkward tasks such as juggling panels at design time and run time, managing Back and Next buttons, storing data between wizard steps, or any of the other little headaches of the past. The simplicity and reusability of the Wizard control is appealing and provides a quick and familiar way to collect data from users.
Steve C. Orr is an MCSD and a Microsoft MVP in ASP.NET. He s been developing software solutions for leading companies in the Seattle area for more than a decade. When he s not busy designing software systems or writing about them, he can often be found loitering at local user groups and habitually lurking in the ASP.NET newsgroup. Find out more about him at http://SteveOrr.net or e-mail him at mailto:[email protected].