ASP.NET Atlas实现网站模块(版块)拖放(Drag & Drop)效果

壤驷俊逸
2023-12-01
基本上,Atlas中可拖放的UI由如下两个部分实现:
可拖动的对象以及投放目标对象。可拖动的对象就是在页面中可以被鼠标移动的DOM元素(例如网上商城中的物品),而投放目标对象则是页面中可以接收可拖动对象的,作为容器的DOM元素(例如网上商城中的购物车)。Atlas允许您通过实现IDragSource接口来定义自己的可拖动对象,实现IDropTarget接口来定义自己的投放目标对象。当然您可以同时实现上述两个接口(比如,您希望用户可以在页面上自由拖动并安排购物车的位置)。
一个DragDropManager对象。DragDropManager是一个全局对象,将在运行时被自动初始化(当然,您需要在ScriptManager中显示声明引用AtlasUIDragDrop脚本)。您可以使用Sys.UI.DragDropManager访问到它。它的主要功能是通过调用IDragSource以及IDropTarget接口提供的方法来启动拖放操作以及注册投放目标对象。通常情况下,您不需要考虑太多关于DragDropManager的事情。
这样,通常情况下使用Atlas创建可拖放的UI有如下两个步骤:
通过实现IDragSource接口来创建可拖动的对象,实现IDragSource接口的对象应该负责调用DragDropManager的startDragDrop()方法以开始拖动的操作(通常这个步骤应该放在处理mouse down事件中实现)。每个可拖动的对象都有自己的dataType属性,可以用来定义相同类型拖放对象。
通过实现IDropTarget接口来创建投放目标对象,实现IDropTarget接口的对象应该在DragDropManager中调用registerDropTarget()注册自己。每个投放目标对象都有自己的acceptedDataTypes属性,用来指定该投放目标对象可以接受何种dataType属性的可拖动对象。
总体上,拖放操作开始于一个可拖动对象调用DragDropManager的startDragDrop()方法,然后,DragDropManager接管了其它的操作,它将负责调用可拖动对象的IDragSource接口方法以及投放目标对象的IDropTarget接口方法来协调二者的关系,以及相应的UI变化。
Atlas提供了一些内建的实现了IDragSource以及IDropTarget接口的Behavior(关于Behavior,请参考:在ASP.NET Atlas中创建自定义的Behavior)供我们使用。显然,下列客户端Behavior都实现了IDragSource或IDropTarget接口中的至少一个。
DragDropList Behavior可以为一组控件增加拖放功能。典型应用就是使ListView控件(关于ListView,请参考:使用ASP.NET Atlas ListView控件显示列表数据)实现拖放功能。
DraggableListItem Behavior可以在一个DragDropList中定义一个拖动对象。可以应用在ListView的ItemTemplate上,使列表中的每一项都可以拖动。
DataSourceDropTarget Behavior用来把数据通过拖放的方式加入到DataSource控件(关于DataSource,请参考:Atlas命名空间Sys.Data下控件介绍——DataSource和XMLDataSource)中。
FloatingBehavior Behavior可以使某个控件浮动在页面上,并可随意移动。  
----------------------------------------------
在本篇中我将使用Atlas的DragDropList Behavior配合Atlas的ListView控件(关于ListView,请参考:使用ASP.NET Atlas ListView控件显示列表数据)来实现一个用户可通过拖拽重新排列内容的页面。大概类似Start与Windows Live的样子,或者,如果你熟悉ASP.NET中的Web Parts,也差不多。当然,这里仅仅是一个演示,不可能做出同样复杂的功能和眩目的效果。您可以在本文的最后下载到这个DEMO的源文件。

首先,一个ScriptManager是必不可少的,不要忘记在其中引入AtlasUIDragDrop脚本文件,它不是Atlas默认加载的。

<atlas:ScriptManager ID="scriptManager" runat="server">
    <Scripts>
        <atlas:ScriptReference ScriptName="AtlasUIDragDrop" />
    </Scripts>
</atlas:ScriptManager>

然后,让我们在页面上添加一个静态的布局,这将是用户加载页面之后看到的初始布局,然后再考虑添加动态的Atlas标记使其能够自由拖动。这里我将创建左右两个区域,区域中的内容既可以在区域之间拖动以改变布局,也可以在本区域内拖动以改变顺序。可拖拽的部分将被包含在一个div中,内部包含任意的控件(可为ASP.NET服务器端控件)。

<div id="leftArea" class="list1">
    <div id="content1" class="item">
        <div id="content1Title" class="itemTitle">Content 1</div>
        <div class="itemContent">
            <asp:Login ID="myLogin" runat="server"></asp:Login>
        </div>
    </div>
    <div id="content2" class="item">
        <div id="content2Title" class="itemTitle">Content 2</div>
        <div class="itemContent">
            Dflying's Item
        </div>
    </div>
</div>

<div id="rightArea" class="list2">
    <div id="content3" class="item">
        <div id="content3Title" class="itemTitle">Content 3</div>
        <div class="itemContent">
            <asp:Calendar ID="myCalendar" runat="server" CssClass="centered"></asp:Calendar>
        </div>
    </div>
</div>

在上面的代码中,我加入了两个区域和三个panel,声明了页面的初始样子。下面让我们加入两个模版:一个用来表示当拖动元素经过可投放区域时,可投放区域高亮的样式(dropCueTemplate)。一个用来表示当某个可投放区域为空的时候的样式(emptyTemplate)。

<div style="display:none;">
    
    <div id="dropCueTemplate" class="dropCue">
    </div>
    
    <div id="emptyTemplate" class="emptyList">
        Drop content here.
    </div>
</div>

恩,还有一些CSS的定义,为方便您的理解,也列在下面:
body, input {font-family:Verdana; font-size: 0.7em;}
.list1{width: 45%; float: left}
.list2{width: 45%; float: right}
.item{background:#fff;}
.itemContent{padding:5px;text-align:center;}
.itemTitle{background:#e5ecf9;font-weight:bold;cursor:move;}
.dropCue{border:dashed 1px #ff0000;}
.emptyList{text-align:center;}

OK,现在可以添加Atlas标记让页面真得动起来了:)上面定义的两个投放区域将被添加DragDropList Behavior以成为Atlas控件。

<control id="leftArea">
    <behaviors>
        <dragDropList dataType="HTML" acceptedDataTypes="'HTML'" dragMode="Move" direction="Vertical">
            <dropCueTemplate>
                <template layoutElement="dropCueTemplate" />
            </dropCueTemplate>
            <emptyTemplate>
                <template layoutElement="emptyTemplate" />
            </emptyTemplate>
        </dragDropList>
    </behaviors>
</control>


<control id="rightArea">
    <behaviors>
        <dragDropList dataType="HTML" acceptedDataTypes="'HTML'" dragMode="Move" direction="Vertical">
            <dropCueTemplate>
                <template layoutElement="dropCueTemplate" />
            </dropCueTemplate>
            <emptyTemplate>
                <template layoutElement="emptyTemplate" />
            </emptyTemplate>
        </dragDropList>
    </behaviors>
</control>

在上面的代码中,我们将leftArea以及rightArea提升为Atlas控件,并且添加了DragDropList Behavior。这两个DragDropList包含了一些类型为HTML的内容,也将可以接受类型为HTML的内容被投放在其中(由dataType以及acceptedDataTypes属性设定)。这两个DragDropList排列内容的方向为Vertical(可以为Vertical或者Horizontal,由direction属性设定)。并且拖拽的方式为Move(可以为Move或者Copy,前者将拖动元素移动,移动后原处不再存在;后者将拖动元素拷贝,移动后原处还存在。由dragMode属性设定)。还指定了上面定义dropCueTemplate和emptyTemplate两个模版。
下面来定义可拖动的元素:

<control id="content1">
    <behaviors>
        <draggableListItem handle="content1Title" />
    </behaviors>
</control>
<control id="content2">
    <behaviors>
        <draggableListItem handle="content2Title" />
    </behaviors>
</control>
<control id="content3">
    <behaviors>
        <draggableListItem handle="content3Title" />
    </behaviors>
</control>


 类似资料: