使用 ASP.NET 2.0 向导控件






3.88/5 (12投票s)
2006 年 9 月 1 日
2分钟阅读

104716
如何在运行时动态创建 ASP.NET 2.0 向导控件并加载子控件。
引言
本文演示了如何在运行时在 ASP.NET 2.0 Wizard
控件中加载控件并附加事件处理程序。 该演示是一个简单的测验程序,提示用户输入他们想要加载到 Wizard
控件中的问题数量。 输入的问题数量决定了运行时创建的 WizardStep
的数量以及为 Wizard
控件创建的控件组的数量。
该演示将显示一个 Image
控件,该控件显示一个标志,后跟一个带有三个选项供用户选择的 RadioButtonList
。 当用户单击“完成”按钮时,程序会计算总的正确答案。 该演示是使用 ASP.NET 2.0 开发的,数据存储在 SQL Server 2005 表中。
下图 1 提示用户输入要在 Wizard
控件中加载的问题数量。
下图 2 显示了加载了五个问题的向导。 每个问题(即 WizardStep
)都加载了一个 Image
控件和一个带有预定义选项的 RadioButtonList
。 图像和 RadioButtonList
选项存储在 SQL Server 表中。
用户在 RadioButtonList
中进行正确的选择,然后单击“下一步”按钮以移动到下一个 WizardStep
。 用户还可以单击 SideBar
并以非顺序方式导航到其他 WizardStep
。
下图 3 显示了当单击“完成”按钮时,通过循环遍历 Wizard
控件中先前的用户选择来计算分数。
很简单……现在让我们谈谈这些屏幕背后的代码。 图 1 提示用户输入,并使用 Server.Transfer()
移动到图 2 中的屏幕。在图 2 的设计屏幕中,只需要一个 PlaceHolder
控件和一个 Label
控件。 PlaceHolder
控件用于托管运行时创建的 Wizard
控件。 Label
控件用于显示计算出的分数。 以下代码在图 2 的 Page_Load
事件中实现。
using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Microsoft.ApplicationBlocks.Data;
using System.ComponentModel;
public partial class TestWizardControl1 : System.Web.UI.Page
{
string thisConnectionString =
ConfigurationManager.ConnectionStrings[
"PracticeDataConnectionString"].ConnectionString;
System.Data.DataSet thisDataSet = new System.Data.DataSet();
protected void Page_Load(object sender, EventArgs e)
{
Wizard WizardControl = new Wizard();
WizardControl.Height = Unit.Pixel(150);
WizardControl.Width = Unit.Pixel(200);
WizardControl.Style["Top"] = "111px";
WizardControl.Style["Left"] = "333px";
WizardControl.Style["Position"] = "absolute";
// The demo uses a Session Variable titled “HowManySteps”
// collected from Fig. 1 to determine the size
// of the Wizard control at run-time. The Wizard Control has an
// initial index of 0. Therefore, subtracting 1 from
// the session variable is needed.
int j = Convert.ToInt16(Session["HowManySteps"]) - 1;
for (int i = 0; i <= j; i++)
{
WizardStepBase newStep = new WizardStep();
newStep.ID = "Step" + (i + 1).ToString();
WizardControl.WizardSteps.Add(newStep);
}
//Dynamically attach an EventHandler to calculate
//final score to the FINISH Button
WizardControl.FinishButtonClick += new
WizardNavigationEventHandler(WizardControl_FinishButtonClick);
PlaceHolder1.Controls.Add(WizardControl);
//Create your own ad hoc query or a stored procedure
//to retrieve the image for the Image Control
//and the choices for the RadioButtonList Control.
//The ExecuteDataset method from the Microsoft
//Application Block is used here to call a
//stored procedure name “Wizard_Retrieve”.
thisDataSet = SqlHelper.ExecuteDataset(
thisConnectionString, "Wizard_Retrieve");
for (int i = 0; i < WizardControl.WizardSteps.Count; i++)
{
//Use a variable (ex. A in the code below)
//to tabulate the Image Control and
//RadioButtonList Control for each WizardStep.
//For example, WizardStep1 will
//contain Image1 and RadioButtonList1.
//WizardStep2 will contain Image2 and
//RadioButtonList2 and so on.
int A = i + 1;
Image ImageControl = new Image();
ImageControl.ID = "Image" + A.ToString();
ImageControl.Width = Unit.Pixel(120);
ImageControl.Height = Unit.Pixel(75);
WizardControl.WizardSteps[i].Controls.Add(ImageControl);
Image IMG = (Image)
WizardControl.WizardSteps[i].FindControl("Image" + A.ToString());
IMG.ImageUrl = thisDataSet.Tables[0].Rows[i][0].ToString().Trim();
RadioButtonList RadioButtonListControl = new RadioButtonList();
RadioButtonListControl.ID = "RadioButtonList" + A.ToString();
WizardControl.WizardSteps[i].Controls.Add(RadioButtonListControl);
RadioButtonList RBL = (RadioButtonList)
WizardControl.WizardSteps[i].FindControl(
"RadioButtonList" + A.ToString());
RBL.Width = Unit.Pixel(180);
RBL.Height = Unit.Pixel(100);
RBL.Items.Clear();
//Use another loop to load the RadioButtonList
//options for each WizardStep
for (int x = 1; x < 4; x++)
{
RBL = (RadioButtonList)
WizardControl.WizardSteps[i].FindControl(
"RadioButtonList" + A.ToString());
RBL.Items.Add(new ListItem(
thisDataSet.Tables[0].Rows[i][x].ToString().Trim()));
}
RBL.SelectedIndexChanged += new EventHandler(RBL_SelectedIndexChanged);
}
}
//Create a EventHandler to process the
//SelectedIndexChanged event for the
//RadioButtonList in each WizardStep.
//Use a HiddenField Control to store the
//selected answer. Concatenate all answers into
//a single string. Parse the answer
//during the FINISH Button Click event to calculate final score.
public void RBL_SelectedIndexChanged(object sender, EventArgs e)
{
RadioButtonList RBL = (RadioButtonList)sender;
if (HiddenField1.Value != string.Empty)
{
HiddenField1.Value = HiddenField1.Value.ToString() +
"/" + RBL.SelectedValue.ToString();
}
else
{
//bypass initial delimiter "/"
HiddenField1.Value = RBL.SelectedValue.ToString();
}
}
public void WizardControl_FinishButtonClick(object sender, EventArgs e)
{
Wizard WZ=(Wizard)sender;
char[] DelimiterChar = { '/' };
string[] Answer = HiddenField1.Value.Split(DelimiterChar);
thisDataSet = SqlHelper.ExecuteDataset(thisConnectionString,
"Wizard_Retrieve");
int score = 0;
for (int i = 0; i < WZ.WizardSteps.Count; i++)
{
if (thisDataSet.Tables[0].Rows[i][4].ToString().Trim()
== Answer[i].Trim())
{
score = score + 1;
}
}
lblMessage.Text = "Your score is " + score.ToString() +
" out of a total of " +
(WZ.WizardSteps.Count).ToString();
}
}
简而言之,这只是一个简单的演示,展示了使用 Wizard
控件的一种方式。 您将需要从 Web 下载标志(CIA World Fact Book 是一个很好的标志来源),或者您可以输入自己的测验问题以使该演示成为在线调查或在线测试。 为了进一步改进上述演示,您可以实现 Page.RegisterHiddenField()
方法以及 IPostBackDataHandler
接口,并调用 Page.RegisterRequiresPostBack()
以在将托管该控件的网页发布回 Web 服务器时显示先前 WizardStep
中的选择。 此外,标志图像或文本问题以及 RadioButtonList
选项都可以打包到资源文件中,而不是作为记录从 SQL Server 表中检索它们。
同时,希望您喜欢这篇文章,并发现上面的示例在您的编程场景中很有用且可以适应。 谢谢!