Text=”Did you know that ASP.NET is the newest Microsoft technology for building Web applications?” Runat=”server” /> Creating a Multipage Wizard This final section discusses how you can
Trang 1break;
}
}
</script>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<style type=”text/css”>
html
{
font:14px Arial,Sans-Serif;
}
</style>
<title>Web Survey</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:Label
id=”lblLanguage”
Text=”What language do you use to develop Web applications?”
Runat=”server” />
<br />
<asp:DropDownList
id=”ddlLanguage”
ToolTip=”Web application language (reloads form)”
AutoPostBack=”true”
Runat=”server”>
<asp:ListItem Text=”Select Language” />
<asp:ListItem Text=”ASP Classic” />
<asp:ListItem Text=”ASP.NET” />
</asp:DropDownList>
<br /><br />
<asp:PlaceHolder
id=”PlaceHolder1”
Runat=”server” />
<asp:Button
id=”btnSubmit”
Text=”Submit”
OnClick=”btnSubmit_Click”
Runat=”server” />
Trang 2<hr />
<asp:Literal
id=”ltlResults”
Runat=”server” />
</div>
</form>
</body>
</html>
WEB STANDARDS NOTE
The DropDownList control in Listing 7.15 reloads the page automatically when you
select a new option You should never reload a page without warning the user because
this can be confusing for someone who uses an assistive device such as a screen
reader In Listing 7.15, a warning is added to the ToolTip property of the
DropDownList control
Depending on the user’s selection from the DropDownList control, one of two User
controls is loaded in the Page_Load() event handler: ASPSurvey.ascx or
ASPNetSurvey.ascx These controls are contained in Listing 7.16 and Listing 7.17
When you submit the survey form, the btnSubmit_Click() method executes This method
casts the User control loaded in the form to the correct type It casts the User control to
either the ASPSurvey or the ASPNetSurvey type
The page in Listing 7.16 includes two <%@ Reference %> directives These reference
direc-tives enable you to cast the User control to the correct type so that you can access
custom properties of the control such as the KnowSlow and KnowOutdated properties
LISTING 7.16 ASPSurvey.ascx
<%@ Control Language=”C#” ClassName=”ASPSurvey” %>
<script runat=”server”>
public bool KnowSlow
{
get { return chkSlow.Checked; }
}
public bool KnowOutdated
{
Trang 3get { return chkOutdated.Checked; }
}
</script>
<asp:CheckBox
id=”chkSlow”
Text=”Did you know that ASP Classic is slow?”
Runat=”server” />
<br /><br />
<asp:CheckBox
id=”chkOutdated”
Text=”Did you know that ASP Classic is outdated?”
Runat=”server” />
<br /><br />
LISTING 7.17 ASPNetSurvey.ascx
<%@ Control Language=”C#” ClassName=”ASPNetSurvey” %>
<script runat=”server”>
public bool KnowFast
{
get { return chkFast.Checked; }
}
public bool KnowNewest
{
get { return chkNewest.Checked; }
}
</script>
<asp:CheckBox
id=”chkFast”
Text=”Did you know that ASP.NET is fast?”
Runat=”server” />
<br /><br />
<asp:CheckBox
id=”chkNewest”
Trang 4Text=”Did you know that ASP.NET is the newest Microsoft
technology for building Web applications?”
Runat=”server” />
<br /><br />
Creating a Multipage Wizard
This final section discusses how you can create a multipage wizard by dynamically loading
different User controls into the same page This is going to be a complicated sample, but it
is a realistic sample of situations when you would want to load User controls dynamically
(see Figure 7.6)
FIGURE 7.6 Displaying a wizard with a series of User controls
Imagine that you must create a form with 200 questions in it Displaying all 200
ques-tions to a user in a single form would be overwhelming Instead, it makes more sense to
break the form into multiple pages Each page of questions can be represented with a
User control
First, you need to define an interface, named the IWizardStep interface, which all the User
controls will implement An interface enables you to know, in advance, that a User
control supports a particular set of properties or methods
Trang 5NOTE
You need to add the interface in Listing 7.18 to your application’s App_Code folder In
Visual Web Developer, create the interface by selecting Website, Add New Item, select
Class Visual Web Developer prompts you to create the App_Code folder
The IWizardStep interface is contained in Listing 7.18
LISTING 7.18 IWizardStep.cs
public interface IWizardStep
{
void LoadStep();
bool NextStep();
}
The interface in Listing 7.18 contains two methods: LoadStep() and NextStep() The
LoadStep() method is called when a User control is first loaded The NextStep() method
is called when the Next button is clicked in the wizard
The NextStep() method returns a Boolean value If the NextStep() method returns the
value False, the user doesn’t advance to the next wizard step
This wizard consists of the three wizard steps contained in Listing 7.19, Listing 7.20, and
Listing 7.21
LISTING 7.19 WizardSteps\Step1.ascx
<%@ Control Language=”C#” ClassName=”Step1” %>
<%@ Implements Interface=”IWizardStep” %>
<script runat=”server”>
public void LoadStep()
{
if (Session[“FirstName”] != null)
txtFirstName.Text = (string)Session[“FirstName”];
if (Session[“LastName”] != null)
txtLastName.Text = (string)Session[“LastName”];
}
public bool NextStep()
{
if (Page.IsValid)
{
Trang 6Session[“LastName”] = txtLastName.Text;
return true;
}
return false;
}
</script>
<h1>Step 1</h1>
<asp:Label
id=”lblFirstName”
Text=”First Name:”
AssociatedControlID=”txtFirstName”
Runat=”server” />
<asp:RequiredFieldValidator
id=”reqFirstName”
Text=”(required)”
ControlToValidate=”txtFirstName”
Runat=”server” />
<br />
<asp:TextBox
id=”txtFirstName”
Runat=”server” />
<br /><br />
<asp:Label
id=”lblLastName”
Text=”Last Name:”
AssociatedControlID=”txtLastName”
Runat=”server” />
<asp:RequiredFieldValidator
id=”reqLastName”
Text=”(required)”
ControlToValidate=”txtLastName”
Runat=”server” />
<br />
<asp:TextBox
id=”txtLastName”
Runat=”server” />
The wizard step in Listing 7.19 contains a simple form that contains Textbox controls
for the user’s first and last name Both TextBox controls are validated with
RequiredFieldValidator controls
The User control in Listing 7.19 implements the IWizardStep interface It contains an
<%@ Implements %> directive at the top of the control
Trang 7The LoadStep() method assigns values to the txtFirstName and txtLastName TextBox
controls from Session state The NextStep() method grabs the values from the
txtFirstName and txtLastName TextBox controls and assigns the values to Session state
The second step of the Wizard is contained in Listing 7.20
LISTING 7.20 WizardSteps\Step2.ascx
<%@ Control Language=”C#” ClassName=”Step2” %>
<%@ Implements Interface=”IWizardStep” %>
<script runat=”server”>
public void LoadStep()
{
if (Session[“FavoriteColor”] != null)
txtFavoriteColor.Text = (string)Session[“FavoriteColor”];
}
public bool NextStep()
{
if (Page.IsValid)
{
Session[“FavoriteColor”] = txtFavoriteColor.Text;
return true;
}
return false;
}
</script>
<h1>Step 2</h1>
<asp:Label
id=”lblFavoriteColor”
Text=”Favorite Color:”
AssociatedControlID=”txtFavoriteColor”
Runat=”server” />
<asp:RequiredFieldValidator
id=”reqFavoriteColor”
Text=”(required)”
ControlToValidate=”txtFavoriteColor”
Runat=”server” />
<br />
<asp:TextBox
id=”txtFavoriteColor”
Runat=”server” />
Trang 8The User control in Listing 7.20 also implements the IWizardStep interface In this step,
the user enters a favorite color
The final wizard step is contained in Listing 7.21
LISTING 7.21 WizardSteps\Step3.ascx
<%@ Control Language=”C#” ClassName=”Step3” %>
<%@ Implements Interface=”IWizardStep” %>
<script runat=”server”>
public void LoadStep()
{
lblFirstName.Text = (string)Session[“FirstName”];
lblLastName.Text = (string)Session[“LastName”];
lblFavoriteColor.Text = (string)Session[“FavoriteColor”];
}
public bool NextStep()
{
return false;
}
</script>
<h1>Step 3</h1>
First Name:
<asp:Label
id=”lblFirstName”
Runat=”server” />
<br />
Last Name:
<asp:Label
id=”lblLastName”
Runat=”server” />
<br />
Favorite Color:
<asp:Label
id=”lblFavoriteColor”
Runat=”server” />
The wizard step in Listing 7.21 displays a summary of answers that the user has provided
in the first two wizard steps (see Figure 7.7) It also implements the IWizardStep interface
Because this is the final wizard step, the NextStep() method always returns the value
False
Trang 9The page in Listing 7.22 contains the actual wizard This page loads each of the wizard
steps
LISTING 7.22 Wizard.aspx
<%@ Page Language=”C#” %>
<%@ Import Namespace=”System.Collections.Generic” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN”
“http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”>
<script runat=”server”>
private List<String> _wizardSteps = new List<String>();
private Control _currentStep;
/// <summary>
/// The current step in the Wizard
/// </summary>
public int StepIndex
{
get
{
if (ViewState[“StepIndex”] == null)
FIGURE 7.7 Displaying the wizard summary step
Trang 10else
return (int)ViewState[“StepIndex”];
}
set
{
ViewState[“StepIndex”] = value;
}
}
/// <summary>
/// Load the list of wizard steps and load
/// current step
/// </summary>
void Page_Load()
{
_wizardSteps.Add(“~/WizardSteps/Step1.ascx”);
_wizardSteps.Add(“~/WizardSteps/Step2.ascx”);
_wizardSteps.Add(“~/WizardSteps/Step3.ascx”);
LoadWizardStep();
}
/// <summary>
/// Load the current wizard step
/// </summary>
private void LoadWizardStep()
{
_currentStep = Page.LoadControl(_wizardSteps[StepIndex]);
_currentStep.ID = “ctlWizardStep”;
plhWizardStep.Controls.Clear();
plhWizardStep.Controls.Add(_currentStep);
((IWizardStep)_currentStep).LoadStep();
ltlStep.Text = String.Format(“Step {0} of {1}”, StepIndex + 1,
_wizardSteps.Count);
}
/// <summary>
/// Disable the Previous and Next
/// buttons when appropriate
/// </summary>
void Page_PreRender()
{
btnPrevious.Enabled = StepIndex > 0;
btnNext.Enabled = StepIndex < _wizardSteps.Count - 1;
}