日期:2010-10-29 浏览次数:20629 次
下面,让我进行简单的分析。首先,我保存了当前的列表中选定项的索引值与当前项。然后,我在当前位置删除该项;之后,在一个较低位置(上一个索引值减1)重新插入该项。这里的逻辑非常简单,那么为什么我还要说明这个问题呢?
借助于这种常规的ASP.NET编程方法,Web表单上面的重排序按钮将会引发一个实现ListBox中重排序的服务器端事件。这是由一个到服务器的回寄触发的;因此,这个回寄可能是一次“繁重的”往返,具体要信赖于表单上的具体内容及因特网速度。
然而,因为这一代码实现的是一个标准ASP.NET回寄过程,所以由ASP.NET使用它的ViewState机制来负责状态处理。当再次生成页面时,列表框内容按要求的顺序正确生成。
当然,你也可以使用与此相同的常规方式在ListMover控件中重新创建这个功能。篇幅所限,我在此省略,只好留待读者您来实现。这个Web表单上包含一对ListBox,还有一些指示从左向右或从右向左移动的按钮。这些按钮的服务器端事件将从一个ListBox中提取选择的项,然后把它添加到另一个列表中;反之亦然。如在刚才的例子中所展示的,ViewState在此能够完好工作以保持这两个ListBox中的项。
三、 目的
下面,我想向你展示如何把刚才描述的这些例子中所用的单个控件放到一个Web表单上。你可能猜出,我将向你展示如何把这两个例子中的功能封装到它们自己的一个Web控件中。借助于与在常规方法示例中描述的相同的服务器端事件模型,我们可以把所有的行为封装到每一个控件中来实现必要的功能。既然每一个控件都能够控制它自己的状态,那么包含它们的Web表单不必要做任何额外的工作。
到目前为止,一切顺利。你可能问:“问题在哪里?”很好,假定页面开发者在含有大量内容的页面上使用这两个控件,而且每当发生一次重排序或移动,都需要到服务器端的重回寄时,这显然不是一个高效的Web站点要实现的。这正是使用一些JavaScript的原因。
在本例中,你要使用JavaScript代码来存取EnhancedListBox控件中ListBox的内容以便在客户端进行重排序。
在ListMover控件中,JavaScript代码将把项从一个列表移动到另一个列表。其最终结果是一样的,但是不需要进行服务器来回传送,因为不需要触发任何回寄。这样以来,你就可以解决即时响应和不需要回馈的问题。
四、 问题
ASP.NET在服务器端生成内容与在客户端生成内容之间有明显的界定。事实上,大部分情况下,这两部分没有关系;因此,问题出现了。其实,一个Web控件只是一个服务器端组件,它负责把HTML生成到浏览器端。的确,标准ASP.NET ListBox控件正是以HTML形式生成一个ListBox(作为一个<select>标签)。
在<select>标签中的<option>子标签可以使用ListBox控件中的Item属性的内容来创建。Item属性在服务器端被填充,而其内容有助于在生成期间构建适当的HTML。这非常类似于生成一个<input>标签的文本框Web控件,而它的Text属性映射到<input>标签的Value属性。每当触发一个到服务器的页面回寄时,ListBox控件的Item属性都被保存到ViewState中,并且在重新生成页面前从ViewState中进行重建。
在EnhancedListBox中进行重排序或在服务器端的ListMover中移动项都非常直接,并且允许支持正常的内置的ViewState机制而不需要我们作任何干扰。但是,当你使用客户端JavaScript添加这一能力来实现它们的功能时,它将破坏ViewState。这些控件并不再转回到服务器端,所以Item集合属性永远不会被保存以便在重新生成时被重载。代之的是,直接在HTML级别上存取生成的<select>标签中的<option>项。你可以借助JavaScript代码移动或重排序控件项;但是,当在页面上再次发生回寄时,你猜发生了什么?在移动(或重排序)开始前,控件的列表项就恢复它们的状态。
我说过,如果功能发生在回寄期间的服务器端,那么,ViewState被保存并且被良好重载,从而使Item集合正确填充。但是,既然你的最终目标是在客户端实现这个功能,那么你就不再需要重新调整Item属性的内容,而是由你依赖的这个属性负责状态存储。现在,你可能会为难了。但是别担心—我有一个解决方案。现在,让我们开始使用必要的客户端脚本代码来开发该控件来实现每一个子控件所需要的功能。然后,我将向你展示如何使它与服务器代码保持重新同步。
五、 EnhancedListBox控件
在这个控件中,你要把两部分