ControlFreak
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.
Wizard Sections
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.
HTML View
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.
<asp:Wizard ID="Wizard1" runat="server"
ActiveStepIndex="0"
BackColor="#E6E2D8" BorderColor="#999999"
BorderStyle="Solid" Height="251px"
Width="357px">
<StepStyle BackColor="#F7F6F3"
BorderColor="#E6E2D8"
BorderStyle="Solid" BorderWidth="2px" />
<SideBarStyle BackColor="#1C5E55"
Font-Size="0.9em"
VerticalAlign="Top" />
<NavigationButtonStyle BackColor="White"
BorderWidth="1px" Font-Names="Verdana"
Font-Size="0.8em"/>
<WizardSteps>
<asp:WizardStep
runat="server" Title="Step 1">
Step 1!
</asp:WizardStep>
<asp:WizardStep
runat="server" Title="Step 2">
Step 2!
</asp:WizardStep>
</WizardSteps>
<SideBarButtonStyle ForeColor="White" />
<HeaderStyle BackColor="#666666"
BorderColor="#E6E2D8"
BorderStyle="Solid" BorderWidth="2px"
Font-Bold="True"
Font-Size="0.9em" ForeColor="White"
HorizontalAlign="Center" />
</asp:Wizard>
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.
Wizard Events
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.
Validation
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.
Conclusion
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:Steve@Orr.net.