作者:小甜甜小小郭 | 来源:互联网 | 2014-05-27 11:53
ASP.NETAJAXControlToolkit中的ReorderList控件将在页面中呈现出一个由数据绑定自动生成的条目列表。用户可以通过鼠标拖动某一项来直接改变该列表中条目彼此之间的相对位置关系,且在拖动的过程中,ReorderList控件提供了丰富的、可定制的视觉效果。当用户
ASP.NET AJAX Control
Toolkit中的ReorderList控件将在页面中呈现出一个由数据绑定自动生成的条目列表。用户可以通过鼠标拖动某一项来直接改变该列表中条目彼
此之间的相对位置关系,且在拖动的过程中,ReorderList控件提供了丰富的、可定制的视觉效果。当用户在某个位置放开鼠标之
后,ReorderList控件也将同样会自动通知与其绑定的数据源控件,以Ajax的异步或整页回送的同步方式更新服务器端数据。
列
表是一切GUI应用程序中都非常常见的元素,而根据用户喜好改变列表中条目的排列顺序也就自然地成为了一个常见的需求。实现这个需求最直观的方法非直接用
鼠标拖动莫属,-18即显示了在Windows的“开始”菜单中通过鼠标拖动改变其中条目排列顺序时的界面样式。
-18 在Windows的“开始”菜单中通过鼠标拖动改变其中条目排列顺序
而
对于传统的Web应用程序来讲,这种对用户最为直观的方式似乎并不是那么易于实现。所以,很多时候我们都会采用在每个条目中添加一对“上移”和“下移”按
钮、或添加一个用来输入次序值的文本框来实现,如-19所示的Mambo
CMS(http://www.mamboserver.com/)的菜单管理界面。这种设计的缺点有很多,包括“上移”和“下移”按钮每次只能将条目移
动一个位置,逐一填写次序值文本框非常麻烦,浪费宝贵页面空间等,而唯一的优势就是实现起来相对简单。
-19 管理列表中的“上移”和“下移”按钮和用来输入次序值的文本框
在 当今流行的Web
2.0应用程序中,这种完全忽视易用性的设计正逐渐地被抛弃,取而代之的是越来越类似桌面应用程序的操作方式。例如流行的在线RSS阅读网站
Bloglines(http://www.bloglines.com/),即允许用户用类似维护Windows开始菜单一样的方式通过鼠标拖动改变列
表条目的位置,如-20所示。
-20 在Web页面中实现通过鼠标拖动改变列表中条目排列顺序
使用ASP.NET AJAX Control
Toolkit中的ReorderList扩展器控件,我们也可以方便地实现这样的功能。
ReorderList
是一个全功能的数据绑定控件,即能够用统一的模版以列表的方式显示多个拥有共同类型的数据条目,比如DataTable中的某一行、Array中的某一项
等,并支持多种模版,例如ItemTemplate、EditItemTemplate、InsertItemTemplate等。若是其绑定的数据条目
中有一个类似Order或Priority之类的表示排序信息的整数类型字段,那么即可将该字段设置为ReorderList的排序字段。这样,当用户拖
动某一项改变其在列表中的位置之后,ReorderList将根据当前的条目次序自动请求服务器,并修改需要更新的条目的排序字段。我们需要做的只是提供
数据源的更新方法以及列表条目的排序字段而已,至于如何增加、减少并且协调列表中各个条目中排序字段的值,都将由ReorderList自动代为处理。
对于用户对列表条目进行的排序操作,ReorderList既可以通过整页的回送,也可以通过Ajax方式的异步回送来通知服务器。而若是
需要对某个列表条目进行编辑或删除,则必须使用传统的整页回送模型,当然,我们仍然可以用UpdatePanel将该ReorderList包围起来以得
到我们所期望的Ajax行为。
ReorderList控件继承于System.Web.UI.WebControls.CompositeDataBoundControl,也
就自然拥有了CompositeDataBoundControl数据绑定控件的所有属性/方法/事件,声明ReorderList控件时所常用的属性标
签如表10-5所示。
10-5 声明ReorderList控件时的常用属性标签
DataSourceID :页面中某个DataSource控件的ID,用于通过数据绑定自动生成列表项目。
DataKeyField :数据源中键字段的名称,该字段中的值应该在所右记录中是唯一且不变的,ReorderList将用条目中该字段的值作为记录的标志,将在更新/删除中使用。
AllowReorder :是否允许用户对列表中的项目进行重新排序,若指定了,则该属性将自动被设置为true。
SortOrderField :数据源中作为排序字段的名称。在用户进行重新排序之后,ReorderList将自动修改需要更新的条目的该字段
DragHandleAlignment :条目的可拖动区域与条目之间的相对位置关系。可选Top(上部)、Bottom(下部)、Left(左边)和Right(右边)。
PostBackOnReorder :若设置该属性值为true,则当用户对列表中的项目进行重新排序之后,将自动引发一次整页的回送。否则将以异步回调的方式向服务器端发送请求。
EditItemIndex :列表中当前处于编辑模式下的项目的索引值。
ShowInsertItem :若该属性值为true,则列表中将显示出一个用来添加新条目的特殊行,即模版中定义的内容。
ItemInsertLocation :插入的新行在整个列表中的位置。可选Beginning(第一项)或End(最后一项)。
<ItemTemplate >:该标签内将定义列表中普通条目的模版。
<DragHandleTemplate >:该标签内将定义列表条目中可拖放区域的模版。用户只有在该区域中拖拽才能够对该条目进行重排序。
<ReorderTemplate >:该标签内将定义拖动列表条目时列表中可投放区域的模版。
<InsertItemTemplate >:该标签内将定义用来添加新条目的特殊行的模版。
<EditItemTemplate >:该标签内将定义处于编辑状态中的列表条目的模版。
<EmptyListTemplate >:该标签内将定义空列表的模版。若列表中没有任何条目,则将显示出该模版中定义的内容。
需要特别注意的是,ReorderList控件并不会在客户端自动根据SortOrderField对条目进行排序,因此我们在进行数据绑定的时
候,要保证条目已经按照SortOrderField进行了排序。事实上,SortOrderField属性也仅仅在更新排序信息时使用。换句话
说,ReorderList将只负责更新条目的SortOrderField属性,而并不负责根据该属性对项目排序。
对于PostBackOnReorder属性,若该ReorderList控件将只提供对项目重新排序的功能,则应该将其设置为
false,这样可以充分利用ReorderList自带的异步回调功能。而若是该ReorderList控件同样支持对条目的添加、删除、编辑等复杂功
能,则应该将PostBackOnReorder属性设置为true,并用UpdatePanel包围该ReorderList,以期得到Ajax的异步
回送功能。
10.4.3 示例程序:可排序的音乐列表
在本示例程序中,我们将基于前面Rating控件的音乐列表,使用ReorderList控件让用户可以根据喜好通过简单直观的鼠标拖动改变某个音乐在列表中的位置。
回到-16中所示的MusicEntry类的类图上,可以看到MusicEntry类包含了一个名为Order的Int类型属性,该属性即将用来存储音乐在列表中的次序。
-16 MusicEntry类的类图
在初始化10条肖邦的名曲时,我们已经依照顺序分别指定了其Order属性为0-9。但由于ReorderList控件将在运行时改变某些
MusicEntry的Order属性,所以在MusicData类中的用来返回所有音乐列表的GetMusicList()方法中,我们还要首先对现有
的MusicEntry根据其Order属性进行排序。修改后的GetMusicList()方法如下:
[DataObjectMethod(DataObjectMethodType.Select)]
public static List
GetMusicList()
{
data.Sort(CompareMusicEntry);
return data;
}
注意其中第一行调用了List<>类型的Sort()方法,对其中的条目进行排序。在调用Sort()方法时,我们传递了一个名为CompareMusicEntry()的静态方法,该方法将用来比较并返回两个MusicEntry对象的排列次序关系:
private static int CompareMusicEntry(MusicEntry x, MusicEntry y)
{
return x.Order.CompareTo(y.Order);
}
从上述CompareMusicEntry()代码中可以看到,MusicEntry对象的顺序将由其Order属性决定。
然后,在MusicData类中添加一个用来更新MusicEntry的方法,该方法用来更新集合中的某个MusicEntry对象,也将
被指定为页面中ObjectDataSource控件的Update方法,并由ReorderList控件通过ObjectDataSource控件进行
调用:
[DataObjectMethod(DataObjectMethodType.Update)]
public static void UpdateMusic(MusicEntry music)
{
for (int i = 0; i < data.Count; ++i)
{
if (data[i].Id == music.Id)
{
m_data[i] = music;
break;
}
}
}
让我们举一个例子说明ReorderList是如何通过ObjectDataSource调用该UpdateMusic()方法的。假如我们有了
a、b、c、d四条音乐,它们的Order属性分别为1、2、3、4。现在用户将第4条,即d拖动到了a、b之间,拖动后的四条音乐的顺序即为a、d、
b、c。这时,ReorderList将首先调用该UpdateMusic()方法将拖动条目,即d的Order属性设置为其前面一条——a的Order
属性加1,即2。然后再调用两次UpdateMusic()方法,分别设定c和d的Order属性为其当前值加1,即3和4。这样,在
ReorderList完成了这3次UpdateMusic()的调用之后,a、b、c、d四条音乐的Order属性就分别变为了1、3、4、2,按照
Order进行排序,四条音乐的顺序将变成我们所期望的a、d、b、c,这样也就完成了一次调整顺序的全过程。
搞清楚ReorderList的实现方法之后,让我们接下来完成这个示例程序:新建一个ASP.NET页面并添加ScriptManager控件,然后添加一个ObjectDataSource控件:
"Music Entry" SelectMethod="GetMusicList" TypeName="MusicData" UpdateMethod=
"UpdateMusic">
可以看到,除了设定UpdateMethod属性为前面刚刚添加到MusicData类中的UpdateMusic()方法之外,该ObjectDataSource控件的所有声明都和前面Rating控件示例程序中的ObjectDataSource完全相同。
接下来添加ReorderList控件,为了简单起见,我们的示例程序将只演示ReorderList的改变条目顺序功能。诸如添加/删除/修改条目的实现与我们熟悉的其他模版化数据绑定控件的实现方式完全相同,这里不赘。ReorderList控件的
DragHandleAlignment="Left" PostBackOnReorder="false" DataSourceID="musicDataSource"
DataKeyField= "Id" Sort OrderField="Order" runat="server">
...
...
...
在上面的定义中,我们指定了DragHandleAlignment属性为Left,即将可拖动区域置于条目的左边。因为这里只需要改变条目顺序的
功能,所以PostBackOnReorder属性设置为false,让ReorderList控件使用其内建的异步回调功能。DataSourceID
属性指向了前面定义的ID为musicDataSource的ObjectDataSource。DataKeyField和
SortOrderField属性分别设置为MusicEntry类的Id和Order属性,让ReorderList能够根据Id属性更新相应的
MusicEntry对象的Order属性。
因为要用到ReorderList的鼠标拖动排序功能,所
以、和
模版都是必须指定的,让我们从开始:
中将定义列表中普通条目,即每一条音乐的模版。这里我们只显示其评级信息,同样使用了Rating控件。这部分
StarCssClass="ratingStar" FilledStarCssClass="filledRatingStar" EmptyStarCssClass="emptyRatingStar" CurrentRating='<%# Bind("Rating") %>'
MaxRating="5" ReadOnly="true">
我们希望将音乐的评级信息显示在条目的右边,所以Rating控件的CssClass属性所指定的rating的定义将如下所示:
.musicList .rating
{
float: right;
}
对于,则相对来说比较简单:
Drop Here!
其中仅仅定义了一个包含“Drop Here!”字样的
元素,该
元素应用的CSS
Class的定义如下:
.musicList .dragDue
{
margin: 1px 5px;
padding: 2px;
border: 1px dashed #555;
color: #555;
text-align: center;
}
可以看到,“Drop Here!”将居中显示,且整个
将显示出灰色的虚线边框。
内将定义列表条目中可拖放区域的模版,用户只有在该区域中拖拽才能够对该条目进行重排序。这里我们通过数据绑定让其显示本条音乐的名称,即让用户在音乐名称上拖动即可对该条音乐进行重新排序:
Text='<%# Bind("Name") %>'>
注意到该Label应用的CSS Class为dragHandle,该CSS
Class的定义如下,注意其中粗体部分定义的鼠标指针样式:
.musicList .dragHandle
{
width: 300px;
margin: 1px 5px;
padding: 2px;
cursor: move;
display: block;
border: 1px solid #fff;
}
这样即完成了整个ReorderList的定义,该ReorderList的完整
DragHandleAlignment ="Left" PostBackOnReorder="false" DataSourceID="musicDataSource"
DataKeyField="Id" SortOrderField="Order" runat="server">
StarCssClass = "ratingStar" FilledStarCssClass="filledRatingStar"
EmptyStarCssClass="emptyRatingStar" CurrentRating='<%# Bind("Rating") %>'
MaxRating="5"ReadOnly="true">
Drop Here!
runat="server" Text='<%# Bind("Name") %>'>
编译并在浏览器中查看该页面,将看到如-21所示的音乐列表。
-21 可改变项目次序的音乐列表界面
-21中同样可以看到,当鼠标悬停到某条音乐的名称上时,鼠标指针将变成移动的样式。在这十首曲目中,我最喜欢目前位于倒数第二位的
“Fantaisie-Impromptu in C-Sharp Minor, Op. 66”
(《幻想即兴曲》),它让我想起了儿时练习钢琴时那段美好兼痛苦的时光。将鼠标移动到该曲目之上,按下左键开始拖动,如-22所示。
-22 拖动倒数第二项:“Fantaisie-Impromptu in C-Sharp Minor, Op. 66”
可以看到,随着拖动该项在列表中移动,所有鼠标当前位置上的音乐条目均纷纷为其让位,并显示出定义在中定义的带有虚线边框的“Drop
Here!”文字。
继续拖动直至第一位后放开鼠标左键,“Fantaisie-Impromptu in C-Sharp Minor, Op.
66”这个条目就这样被提到了最前面。由于ReorderList已经将列表中音乐的当前次序保存到了服务器端,即使刷新页面或另开窗口访问该页面,当前
的排序信息将依然保留,如-23所示。
推荐阅读
本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ...
[详细]
蜡笔小新 2024-12-27 18:20:43
本文介绍如何在Linux服务器之间使用SCP命令进行文件传输。SCP(Secure Copy Protocol)是一种基于SSH的安全文件传输协议,支持从远程机器复制文件到本地服务器或反之。示例包括从192.168.45.147复制tomcat目录到本地/home路径。 ...
[详细]
蜡笔小新 2024-12-26 07:43:09
预览截图html部分123456789101112用户登入1314邮箱名称邮箱为空15密码密码为空16登 ...
[详细]
蜡笔小新 2024-12-20 09:57:07
本文介绍如何使用 Oracle 存储函数查询特定员工的年收入。我们将详细解释存储函数的创建过程,并提供完整的代码示例。 ...
[详细]
蜡笔小新 2024-12-28 09:49:42
本文介绍了如何使用 CSS 实现液态的三栏布局,其中各栏具有不同的宽度设置。通过调整容器和内容区域的属性,可以实现灵活且响应式的网页设计。 ...
[详细]
蜡笔小新 2024-12-28 02:40:28
本文详细介绍了 Linux 系统启动过程中常见的 MBR 扇区和 GRUB 引导程序故障及其解决方案,涵盖从备份、模拟故障到恢复的具体步骤。 ...
[详细]
蜡笔小新 2024-12-27 20:40:29
1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ...
[详细]
蜡笔小新 2024-12-27 19:32:17
本文介绍了一种通过逐对比较线段来求解交点的简单算法。此外,还提到了一种基于排序的方法,但该方法较为复杂,尚未完全理解。文中详细描述了如何根据线段端点求交点,并判断交点是否在线段上。 ...
[详细]
蜡笔小新 2024-12-26 14:48:56
友盟推出的最新版错误分析工具,专为移动开发者设计,提供强大的Crash收集与分析功能。该工具能够实时监控App运行状态,快速发现并修复错误,显著提升应用的稳定性和用户体验。 ...
[详细]
蜡笔小新 2024-12-26 14:11:47
蜡笔小新 2024-12-26 13:47:54
蜡笔小新 2024-12-26 13:29:32
VPX611是北京青翼科技推出的一款采用6U VPX架构的高性能数据存储板。该板卡搭载两片Xilinx Kintex-7系列FPGA作为主控单元,内置RAID控制器,支持多达8个mSATA盘,最大存储容量可达8TB,持续写入带宽高达3.2GB/s。 ...
[详细]
蜡笔小新 2024-12-26 11:41:58
本文介绍如何使用Python进行文本处理,包括分词和生成词云图。通过整合多个文本文件、去除停用词并生成词云图,展示文本数据的可视化分析方法。 ...
[详细]
蜡笔小新 2024-12-26 08:37:18
本文探讨了并发编程中的关键设计原则,特别是Java内存模型(JMM)的happens-before规则及其对多线程编程的影响。文章详细介绍了DCL双重检查锁定模式的问题及解决方案,并总结了不同处理器和内存模型之间的关系,旨在为程序员提供更深入的理解和最佳实践。 ...
[详细]
蜡笔小新 2024-12-26 01:14:06
本文介绍了多个关于JavaScript的书籍资源、实用工具和编程实例,涵盖从入门到进阶的各个阶段,帮助读者全面提升JavaScript编程能力。 ...
[详细]
蜡笔小新 2024-12-24 16:36:52