- Cross-Page Posting
- Wizard and MultiView Controls
- Profile
- Summary
Wizard and MultiView Controls
This section covers a new collection of controls in ASP.NET 2.0 that simplify the process of collecting data from the user by using a sequence of steps that are all on a single page. The controls include the new Wizard control as well as the View and MultiView controls.
Same Page State Management
Another alternative to storing per-client state across requests is to have the user post back to the same page instead of navigating from one page to another. You can achieve the same sequential set of steps for data collection that you can using multiple pages with this technique by toggling the display of various panels, showing only one of several panels at any given time based on the user's progress. Instead of placing input controls on separate pages, you place them all on the same page, but separate them with Panel (or Placeholder) controls as shown in Figure 4-1. When the user selects the Next button in one panel, the handler for that button sets the visibility of the current panel to false and of the next panel to true.
Figure 4-1 Multipanel page
This technique works well because all of the state for all the controls is kept on a single page, and even when the controls in a particular panel are not displayed, their state is maintained in view state, so programmatically it is just like working with one giant form. It is also quite efficient, since the contents of invisible panels are not even sent to the client browser; just the state of the controls is sent through view state.
Wizard Control
In the 2.0 release of ASP.NET this technique has been standardized in the form of the Wizard control. Instead of laying out the Panel controls yourself and adding the logic to flip the visibility of each panel in response to button presses, you can use the Wizard control to manage the details for you and focus on laying out the controls for each step. The control itself consists of a collection of WizardSteps which act as containers for any controls you want to add. Listing 4-18 shows a sample Wizard control populated with the input elements described in Figure 4-1 (also included is an adjacent Label control to display the data on completion).
Listing 4-18. Sample Wizard control with three steps
<asp:Wizard ID="_infoWizard" runat="server" ActiveStepIndex="0" OnFinishButtonClick="_infoWizard_FinishButtonClick" DisplaySideBar="False"> <WizardSteps> <asp:WizardStep ID="_step1" runat="server" Title="Name"> <table> <tr> <td>First name:</td> <td><asp:TextBox ID="_firstNameTextBox" runat="server" /></td> </tr> <tr> <td>Last name:</td> <td><asp:TextBox ID="_lastNameTextBox" runat="server" /></td> </tr> </table> </asp:WizardStep> <asp:WizardStep ID="_step2" runat="server" Title="Address"> <table> <tr> <td>Street:</td> <td><asp:TextBox ID="_streetTextBox" runat="server" /></td> </tr> <tr> <td>City:</td> <td><asp:TextBox ID="_cityTextBox" runat="server" /></td> </tr> <tr> <td>State/Province:</td> <td><asp:TextBox ID="_stateTextBox" runat="server" /></td> </tr> </table> </asp:WizardStep> <asp:WizardStep ID="_step3" runat="server" Title="Preferences"> <table> <tr> <td>Favorite color:</td> <td><asp:TextBox ID="_colorTextBox" runat="server" /></td> </tr> <tr> <td>Favorite number:</td> <td><asp:TextBox ID="_numberTextBox" runat="server" /></td> </tr> </table> </asp:WizardStep> </WizardSteps> </asp:Wizard> <asp:Label ID="_summaryLabel" runat="server" />
Like most controls in ASP.NET, both the appearance and behavior of the Wizard control are extremely customizable. In the previous example, the control's SideBar portion, which generates a set of navigation hyperlinks on the left side to let the user jump between steps in the wizard without using the Next/Previous buttons, was not displayed. Figure 4-2 shows two different renderings of the Wizard control: the first is exactly how the Wizard control shown in Listing 4-18 would appear, and the second shows the same control with a different formatting applied and with the ShowSideBar attribute set to true. This control also supports templates so that you can completely customize the look and feel of it as desired.
Figure 4-2 Wizard control, unadorned, and with SideBar and formatting
The advantage of working with the Wizard control like this is that it manages all of the details of the sequential interaction with the user, and you can treat all of the input elements in each of the separate steps as if they were all part of a single page. For example, in our OnFinishButtonClick handler for the Wizard control we can easily use all of the data the user has entered. Listing 4-19 shows an example of printing a message back to the user in the form of a label and then hiding the Wizard control as an indicator that the input sequence is complete.
Listing 4-19. Handler for the Wizard's Finish button click event
protected void _infoWizard_FinishButtonClick(object sender, WizardNavigationEventArgs e) { _summaryLabel.Text = string.Format( "<h2>Thank you for submitting your information!</h2>" + "Name: {0} {1}<br /><br/>Address: {2}<br/>" + "{3}, {4}<br /><br />Prefs: {5} {6}<br />", _firstNameTextBox.Text, _lastNameTextBox.Text, _streetTextBox.Text, _cityTextBox.Text, _stateTextBox.Text, _colorTextBox.Text, _numberTextBox.Text); _infoWizard.Visible = false; }
MultiView and View Controls
If you want the ability to toggle among multiple panels on a page but find the Wizard control too constraining, you might instead consider using the MultiView control. A MultiView control consists of several child View controls, and it maintains an active index indicating which of those child views should be visible. In fact, the WizardStep control used by the Wizard control inherits from the View class used by the MultiView, so the similarity is not a coincidence. Unlike the Wizard control, the MultiView renders nothing but the contents of the active view—there are no buttons, links, or titles of any kind. This means that it is up to you to determine how the user switches between the various views. Listings 4-20 and 4-21 show a sample MultiView with three embedded views to collect data from the user. This example uses three link buttons to let the user toggle among the three views by setting the ActiveViewIndex of the MultiView depending on which button was selected.
Listing 4-20. MultiView with LinkButtons
<asp:LinkButton ID="_view1LinkButton" runat="server" OnClick="_view1LinkButton_Click"> View 1</asp:LinkButton> <asp:LinkButton ID="_view2LinkButton" runat="server" OnClick="_view2LinkButton_Click"> View 2</asp:LinkButton> <asp:LinkButton ID="_view3LinkButton" runat="server" OnClick="_view3LinkButton_Click"> View 3</asp:LinkButton><br /> <asp:MultiView ID="_infoMultiView" runat="server" ActiveViewIndex="0"> <asp:View ID="_view1" runat="server"> <table> <tr> <td>First name:</td> <td><asp:TextBox ID="_firstNameTextBox" runat="server" /></td> </tr> <tr> <td>Last name:</td> <td><asp:TextBox ID="_lastNameTextBox" runat="server" /></td> </tr> </table> </asp:View> <asp:View ID="_view2" runat="server"> <table> <tr> <td>Street:</td> <td><asp:TextBox ID="_streetTextBox" runat="server" /></td> </tr> <tr> <td>City:</td> <td><asp:TextBox ID="_cityTextBox" runat="server" /></td> </tr> <tr> <td>State/Province:</td> <td><asp:TextBox ID="_stateTextBox" runat="server" /></td> </tr> </table> </asp:View> <asp:View ID="_view3" runat="server"> <table> <tr> <td>Favorite color:</td> <td><asp:TextBox ID="_colorTextBox" runat="server" /></td> </tr> <tr> <td>Favorite number:</td> <td><asp:TextBox ID="_numberTextBox" runat="server" /></td> </tr> </table> </asp:View> </asp:MultiView>
Listing 4-21. LinkButton handlers for MultiView switching
protected void _view1LinkButton_Click(object sender, EventArgs e) { _infoMultiView.ActiveViewIndex = 0; } protected void _view2LinkButton_Click(object sender, EventArgs e) { _infoMultiView.ActiveViewIndex = 1; } protected void _view3LinkButton_Click(object sender, EventArgs e) { _infoMultiView.ActiveViewIndex = 2; }