您的位置:首页 > 编程语言 > ASP

全面剖析ASP.NET 2.0中的向导控件

2007-09-18 10:27 274 查看
【51CTO.com独家特稿】我相信,每一位读者对于桌面应用中的向导概念肯定不会陌生;但是,在Web开发中,通过HTTP连接实现一个向导并非易事。还好,ASP.NET 2.0中新引入的向导使得这一问题相对容易。在本文中,让我们来详细剖析这个向导控件的使用思路;同时,本文还提供了一个简单的例子供您参考。

一、什么是向导?

无论你进行Web开发还是从事Windows开发,你经常需要使用表单来收集用户输入信息。当需要收集的输入数据能够被分解成特定的类型时,针对每一种类型使用一个相应的表单常常是典型的实现。典型情况下,整个过程可以被分解成各种步骤,每一步负责校验期望数据的一个特定子集。这种多步骤过程通常称作一个“向导”。

一个向导让你实现线性处理(从步骤1到步骤N),但是也允许用户跳过不必要的步骤或返回到前面的步骤以作出某些改变(非线性设计还能够通过编程方式控制,稍后我们会讨论)。在Web上实现一个向导是许多开发者都需要解决的一项任务;但是,在以前管理每一步中的导航和数据集合一直都很复杂。幸好,ASP.NET 2.0提供一个新的向导控件,从而大大简化了这一过程。

为了把一系列表单链接到一个象向导一样的用户接口中,你必须管理表单之间的导航,处理数据存储和管理每一步中的状态。跨页面寄送和显示/隐藏面板是能够应用于ASP和ASP.NET中从而实现构建向导的两项主要的技术。这种跨页面寄送技术包括把第一个页面输入的内容寄送到另一个不同的页面以及用隐藏域来存储以前的内容。借助于显示/隐藏面板技术,我们可以把各种视图加入到单个页面中并且基于当前步骤对其加以显示或隐藏。

第二种技术特别适合于ASP.NET 1.x应用程序。你将在后面看到,显示/隐藏还是ASP.NET 2.0实现向导控件的关键思想。

二、ASP.NET 2.0中的向导控件

ASP.NET 2.0向导(Wizard)控件简化了我们前面要实现的任务。这个控件提供了一种机制允许你轻松地把希望实现的向导构建为一个步骤集合—添加新的步骤或重新排序步骤。你不必为各步骤之间的导航或用户数据存储编写任何基础代码。

为使用向导控件,你只需遵循下面这些简单的步骤:

1. 把一个向导控件拖动到你的Web表单;

2. 把一些控件,图像和文本添加到每一个向导步骤中;

3. 存取该向导在各步骤之间的数据。

向导控件是一个复合控件,它继承自基类CompositeControl并且被集成到Visual Studio 2005的设计器中,它能够进行自身数据回寄以保持视图状态信息。这一事实使得我们能够实现非线性导航并且保证表单元素自动地跨多个向导过程视图重新填充。

一个向导中的每一步都是一种面板(一个文本,标记,图像和定制用户控件的容器)。图1展示了ASP.NET 2.0向导控件的架构。



498)this.style.width=498;" border=0>


图1.Wizard控件结构图[/b]

[/b]

[/b]三、使用向导控件

一个向导控件由四部分组成:头部,当前步骤视图,导航样和侧栏。所有这些组成部分(甚至更多),都可以通过使用一些属性加以修饰。其中,头部、侧栏和导航栏的内容能够通过模板进一步定制。

下面列表1中的代码概括了一个ASP.NET 2.0应用程序中的一个向导控件的典型实现代码。

列表1.典型的向导控件框架:[/b]

[/b]



498)this.style.width=498;" border=0>
[/b]

[/b]

[/b]其中,最顶层属性允许你通过改变控件的字体、边框、颜色和标题来配置它的外观。

四、在向导中加入步骤

上面的块负责收集定义的所有步骤。你可以通过图2中的属性对话框编辑WizardSteps集合。你可以在该集合中添加两种类型的步骤:一个简单的向导步骤或一个模板化向导步骤。在前一种情况下,你添加一个WizardStep控件;在后一种情况下,一个TemplatedWizardStep控件实例被添加到页面上。这两种控件工作方式类似,并且都接收一个显式定义的服务器控件集合。一个WizardStep控件看上去如下所示:



498)this.style.width=498;" border=0>




498)this.style.width=498;" border=0>
[/b]

[/b]

[/b]图2.WizardStep集合编辑器[/b]

[/b]

可以动态地调整一个WizardStep的内容,并且可以通过编程方式添加或删除步骤。然而,为了允许进一步定制,你可以使用TemplatedWizardStep来代替WizardStep以允许用户改变其中的内容和导航模板。默认情况下,你能够拥有三种不同的导航模板:Start[/b],Step[/b]和Finish[/b]。使用TemplatedWizardStep允许你在每一步中拥有不同的导航按钮。

下面是你定义一个模板化步骤的方式:



498)this.style.width=498;" border=0>


该元素相应于一个实现ITemplate接口的对象的实例。这个对象Get或Set模板以便在向导中显示一个页面的内容。当然,你也可以用编程方式定义或改变模板。另外,一个TemplatedWizardStep控件还允许你通过模板来修改导航栏:



498)this.style.width=498;" border=0>


通过添加一个块,你可以全面地控制通常被显示于当前视图底部的导航。你通常使用一个系列按钮来填充这个块,当然也可以使用其它控件。

其实,一个向导步骤只是一个在其中拆解了原始用户接口来构建该向导的表单。因此典型地,一个向导步骤将包含输入控件例如文本框和复选框,下拉列表框,日历控件,校验控件以及其它你可能用于收集用户数据的控件。

所有的Step类都继承自WizardStepBase类。这个基类提供给每一个子类一个属性名字—StepType。该属性Get或Set导航按钮的类型以便在一个向导控件的一个页面中进行显示。默认情况下,步骤的类型可以由控件动态决定。第一个步骤是一个Start[/b]步骤,而最后一个步骤是Finish[/b]步骤;除非是用户专门指定,否则该控件不会自动地把步骤设置为Finish[/b]步骤。所有的其它中间步骤都是普通的步骤。步骤类型之间的主要区别是,按钮列表被显示于导航栏中。一个普通的步骤允许一个用户前后移动,而一个Start[/b]步骤并不显示一个Back[/b]按钮,而一个Finish[/b]步骤不提供任何导航。我们已经提到,所有的这些内置的规则都可以加以改变—如果你使用一个模板化解决方案的话。

下面的列表2显示了一个示例向导的完整源代码,该向导负责收集与把一各新队员添加到一个数据库相关的任何数据。

[/b]

列表2.[/b]数据收集向导完整源码:[/b]

[/b]




498)this.style.width=498;">

雇佣时间
请在此输入备注信息:
[/b]
[b]五、
构建“添加新队员”向导

你可以看到,上面列表中并没有包括任何服务器端代码。你可以把该代码保存到一个ASPX文件中。当启动浏览器运行向导页面时,你会看到如图3所示屏幕快照。



498)this.style.width=498;" border=0>


图3.添加新队员数据向导[/b]

该向导由三步组成。首先你要收集新队员的姓名,私人信息及可选的备注信息。然后,你通过创建一个摘要页面结束此向导。然后,该向导完成该操作,保存任何数据,并且通过一个结束步骤显示最后的消息。如图3所示,你可以很容易地(以声明方式)实现校验功能以确保只有输入了正确数据时用户才能转到下一步。为此,你应该在向导视图中使用ASP.NET校验器控件以便快速进行客户端检查。如果你需要存取任何服务器端资源来校验输入信息的话,你应该使用Transition事件。

ASP.NET 2.0提供可定制的主题(Theme)以使你的向导更具吸引力。一个主题是一组图形化设置(式样表和控件属性),它们能够应用于页面或应用程序中所有的服务器控件上。它们提供一种很巧妙的方法把一种标准的一致性的外观应用到Web页面和控件。主题是以文本文件发布的,并且可以应用于整个应用程序中的所有页面。

你可以在向导的左上角添加一幅图像,这样可以增强视觉吸引力并且也可以传送一些额外信息,特别当你使用一个向导侧栏时(见图3)。

你可以使用多种方法来改变这些控件的外观。为所有的按钮确定一个一致的外观的最容易的方法是定义一个NavigationButtonStyle对象。这个方法可以确保所有的按钮共用一组式样,而且还允许你通过特定的风格(例如CancelButtonStyle)逐个定制按钮。

你可以使用属性控制每一个按钮上的文本—还能够使用图像和可选的文本。下面的例子说明了这一点:

MyWizard.NextStepButtonText=">>";

MyWizard.NextStepButtonImageUrl="...";
【注意】如果两个属性都设置,则文本优先。在上面示例中使用的NextStepButtonXxx属性仅在普通步骤中起作用。显示于开始页面中的“下一步”按钮可以使用一组不同的属性进行定制。

六、向导事件

Wizard控件能够为你代劳一个多步骤输入过程中的许多细节操作,特别是在Web场所下。然而,对于一些核心任务仍然要求手工编码。为此,需要一个事件模型来负责通知何时向导完成一项给定任务—例如移动到下一个或前一个页面,已完成或刚启动某过程等。

除了任何服务器控件具有的典型事件(例如Init,Load和PreRender)外,Wizard控件还提供了一些特定事件(详见MSDN)。其中,绝大多数事件与导航按钮和侧栏元素的点击事件相关。例如,当前活动视图因用户行为改变时,将引发ActiveStepChanged事件。当用户点击导航按钮时,页面发生回寄,并且在缺省页面重新初始化后,第一个被激发的服务器事件将对应于选定按钮的Click[/b]事件。然后,如果前一个调用的事件处理器导致一个视图切换,那么将触发ActiveStepChanged事件。

ActiveStepChanged事件所使用的代理是很简单的—EventHandler—它并不传送任何其它信息,而只是作为一个用于报告某事发生的普通通知。CancelButtonClick事件表示撤销向导,此事件也没有太多的实现细节。

【注意】如果用户依次通过各个向导步骤,而不是在最后一步才提交所有内容时,需要由你来编写“恢复”(即“undo”)代码—当用户选择取消动作而此时可能已经发生某些变化。

所有另外的事件都请求一个更丰富的代理—WizardNavigationEventHandler—它使用WizardNavigationEventArgs类来传送一些其它信息:

public class WizardNavigationEventArgs {

bool Cancel {get; set;}

int CurrentStepIndex {get;}

int NextStepIndex {get;}

}
值得注意的是,所有Click[/b]事件都发生在视图切换之前;该Click[/b]事件是你执行任何必要的校验并且对这一步作出任何决定性结论的最后机会。这里,integer[/b]型属性CurrentStepIndex指示当用户点击页面时的步骤索引值,而NextStepIndex属性指示当前事件处理结束后的新的步骤索引。这种模型非常类似于ASP.NET 1.x在DataGrid的分页技术中所使用的方式。在这种上下文中,PageIndexChanged事件拥有CurrentPageIndex值和NewPageIndex属性,供你参考使用。当然,这还可以使你以编程方式改变执行步骤。

通过把Cancel属性设置为true,任何步骤中所作的改变都可以被抛弃。例如,你定义一个“next”按钮点击相应的处理器,那么当用户点击并看到下一个页面时,你检查输入的姓名是否是你自己提供的已有名单—此时,向导会拒绝切换到下一步骤。下面是一个示例:

void OnNext(object sender,WizardNavigationEventArgs e) {

if (LastName.Text == "Esposito"){

e.Cancel = true;

return;

}

}
为了Get/Set视图控件中的值,我们通常使用基于ASP.NET ID的语法。从技术上讲,这是可以支持的,因为所有的向导视图都是相同的页面,尽管每次仅有一个视图是活动的和可见的。

你可以设置任何要求的事件处理器—这可以通过使用声明方式的基于属性的ASP.NET语法,或使用.NET语言支持的代理(delegate[/b])语法来实现。例如,下列片断展示了如何通过一个属性定义一个事件处理器:

[/url]

FinishButtonClick是添加任何结束向导的代码的地方。然而,大多数情况下,在继续完成步骤前,你可能还想显示一个输入摘要。然而,显示于Finish[/b]步骤视图中的文本只能根据用户在前面的步骤中输入的内容动态地决定。

为了准备并显示该“Finish”步骤,你可以编写一个Next[/b]按钮和Previous[/b]按钮点击处理器,并使其共享相同的初步代码以检查该步骤的类型。你可以如下实现:

WizardStepType t = MyWizard.WizardSteps[e.NextStepIndex].StepType;

if (t == WizardStepType.Finish){

//准备摘要信息并填充“Finish”步骤中的用户界面内容

...

}
在此,你需要检查当前步骤的类型,如果它是一个Finish[/b]步骤的话,你要收集相应的输入数据并且为用户准备摘要数据。前面已提及,一个Finish[/b]步骤在导航栏仅显示Previous[/b]和Finish[/b]按钮以便用户往回移动或结束向导。

输入数据的存储及其与宿主应用程序的集成是通过最后一步来实现的。为此,你需要使用一个FinishButtonClick处理器。

你可以使用MoveTo方法以编程方式移动到一个特定步骤。该方法的原型如下:

public void MoveTo(WizardStep step);
该方法是对ActiveStepIndex属性设置的一个简单包装;而且,它要求你传递进一个WizardStep对象(否则,有可能导致问题)。然而,如果你想跳转到一个特定步骤,那么直接设置ActiveStepIndex属性一样有效。当一个用户在前一个步骤中选择消除进一步显示;此时,这个属性是很有用的。当实现非线性导航时,禁止显示侧栏通常很有用。否则,一个用户可能会随机地跳转到可能不是他们的路径的一部分。

为了得到一个特定步骤的WizardStep对象,你可以通过GetHistory方法存取向导的历史:

public ICollection GetHistory();
GetHistory返回一个WizardStep对象集合。集合项的顺序由用户存取向导中页面的顺序决定。第一个返回的WizardStep对象(索引为0)是当前选定的步骤—如果用户回寄到相同页面的话;否则,第一个WizardStep就是前一个步骤。相应地,第二个对象代表当前视图前面的那个视图,以此类推……

七、向导侧栏(Sidebar)

侧栏是整个向导框架中可选的元素—如果支持的话,它会显示于整个向导界面的左边。其典型的作用在于,向用户提供一个向导中步骤的快速启动式用户接口。默认情况下的Wizard控件是支持侧栏的,但你可以通过把DisplaySideBar属性设置为false而加以隐藏。当使用非线性导航组织向导内容时,隐藏侧栏可能很有用。

注意,侧栏的布局仅是可部分定制的。你可以使用SideBarTemplate属性来定义其内容。为此,你或者可以以声明方式通过标志或以编程方式把一个ITemplate对象加载到SideBarTemplate属性中。无论选择哪个方法,切记该模板必须包含一个ID和DataList。该DataList的ID必须是“SideBarList”并且它的ItemTemplate块必须包含一个ID为“SideBarButton”的按钮对象。任何在该DataList中设置的其它模板都可能引起运行时刻错误。这些ID是通过一组保护型静态成员—DataListID和SideBarButtonID在Wizard类中固定设置的。

在加载时刻,向导控件填充侧栏的按钮栏,这可以动态地生成映射到一个已定义的向导步骤中的每一个按钮。向导通过ID寻找内部DataList并且填写它的用户接口。除了该DataList外,任何其它标记和控件的组合(包括图像)都能够被添加到侧栏中。

八、总结

ASP.NET 2.0 Wizard控件为开发人员创建特征丰富的Web应用程序提供了一种高级“构造块”。篇幅所限,本文没有详细讨论向导控件与数据库的连接,向导各步骤中的数据校验等问题,还望谅解。

[/b]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: