用Atlas实现Drag And Drop功能
- Draggable items and Drop targets. Drageable items是我们在页面中托放的控件,一般都是以Panel的形式,而drop targets是 dragable items的容器。在Atlas中要使一个控件具有drag能力就必须实现IDragSource接口。要成为drop targets则要实现IDropTarget接口。我们也可以创建一个类既实现IDragSource接口也实现IDropTarget接口。
- a DragDropManager 它是一个在运行时的全局范围对象,你可以通过引用Web.UI.DragDropManager来访问这个对象,它一般是用来开始 dragging operations 和注册 drop targets.从这以后DragDropManager就通过调用IDragSource 和 IDropTarget的方法管理drag&drop的操作。
所以,要实现一个很基本的drag&drop UI 我们需要:
- 创建draggable items 通过实现IDragSource接口。实现了该接口的类通过调用Web.UI.DragDropManger.startDrapgDrop()方法来开始dragging操作(典型的是通过鼠标点击来触发此事件)。每一个draggable item都有它的dataType,比如可以通过这个Type我们可以组合draggable items(预定义的dataType是HTML)。
- 创建drop targets 通过实现IDropTarget接口.实现了该接口的类就可以通过调用Web.UI.DragDropManager.registerDropTarget()方法来注册drop target.每一个drop target都有一系列acceptedDataTypes,只有符合这些要求的draggable items才能够托放进来。
从以上可以看出,一个drag&drop操作的流程如下:首先IDragSource对象调用startDragDrop()方法开始drag&drop操作;然后该操作被DragDropManager处理,通过调用IDragSource的方法来实现托放功能,通过调用IDropTarget的方法来注册drop target(s)。
在Atlas框架中内建了一些controls 和 behaviors来实现drag&drop操作。以下的类实现了IDragSource,IDropTarget接口,或者两者都实现了。
- DragDropList 它允许我们对一系列的控件添加drag&drop能力。一个典型的应用就是把它应用在ListView控件中。
- DraggableListItem 它允许我们在一个DragDropList定义一个draggable item。通常把它以ItemTemplate的形式添加到一个ListView中,这样就可以使一系列的items实现drag&drop功能。
- DataSourceDropTarget 我们通过它向一个DataSource控件中添加一个dropped data。
- FloatingBehavior 我们可以把它添加到一个控件中来建立一个浮动的控件。
下面我们来建立一个具体的实例来实现drag&drop功能
首先我们建立一个静态布局的页面,然后我们将通过一些Atlas标记使它具有动态的行为。我建立了两个区域用来放置托放的控件。托放的控件使通过用ASP.NET的控件组成的Panel形式。
<div id="leftArea" class="list1">
<div id="content1" class="item">
<div id="content1Handle" class="itemHandle">Content 1</div>
<div class="itemContent">
<asp:Login ID="myLogin" runat="server"
CssClass="centered"></asp:Login>
</div>
</div>
<div id="content2" class="item">
<div id="content2Handle" class="itemHandle">Content 2</div>
<div class="itemContent">
<asp:TextBox ID="myTextBox" runat="server"></asp:TextBox>
<asp:Button ID="myButton" runat="server"
Text="ClickMe" />
</div>
</div>
</div>
<!-- Right Area -->
<div id="rightArea" class="list2">
<div id="content3" class="item">
<div id="content3Handle" class="itemHandle">Content 3</div>
<div class="itemContent">
<asp:Calendar ID="myCalendar" runat="server"
CssClass="centered"></asp:Calendar>
</div>
</div>
</div>
你可以看到,我在这个静态布局的页面里面创建了两个drop zones和三个content panels。
现在我们需要一些HTML来显示一些高亮的内容当我们拖动panel的时候(the dropCueTemplate,还需要一些HTML来表明一个空的zone的状态(the empty Template).
<div class="templates">
<!-- DropCue Template -->
<div id="dropCueTemplate" class="dropCue"></div>
<!-- Empty Template -->
<div id="emptyTemplate" class="emptyList">Drop content here.</div>
</div>
<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>
右边的区域标记跟上面的类似。在上面的代码中我们把“leftarea”<div>封装到Atlas控件中,并给她添加DragDropList behavior。它具有的数据类型为“HTML”,接受的数据类型也为“HTML”,是Vertical(垂直)的布局(另一个选择是水平的),托放的形式是移动,另一个选择是复制,假如选择的是复制那么它将复制一个Panel到你托放的区域,原来的Panel还在原处。然后再把它的dropCueTemplate和emptyTemplate与我们之前写的HTML结合起来。
然后标记content panel:
<control id="content1">
<behaviors>
<draggableListItem handle="content1Handle" />
</behaviors>
</control>
我们通过draggableListItem behavior使DOM元素“Content1”变成了一个Atlas控件。这样就使得这个content panel可以被托放。handle属性表明托放操作的控制器,在这里我把它设成这个content panel的上面一部分。其他两个content panel跟这个类似。
最后运行下看看效果:)。下面是整个个页面的代码(需要放在Atlas网站中才能运行):
DragDropExample.aspx
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>DragAndDrop UI Example</title>
<atlas:ScriptManager ID="scriptManager" runat="server">
<Scripts>
<atlas:ScriptReference ScriptName="AtlasUIDragDrop" />
</Scripts>
</atlas:ScriptManager>
<style type="text/css">
body{font-family:Verdana;font-size:11px;}
.main{position:relative;width:710px;height:540px;margin:auto;}
.list1{position:absolute;left:0px;height:520px;width:340px;
padding:10px 5px 10px 10px;}
.list2{position:absolute;right:0px;height:520px;width:340px;
padding:10px 10px 10px 5px;}
.item{background:#fff;margin-bottom:5px;background:#fff;}
.itemContent{padding:5px;text-align:center;}
.itemHandle{height:15px;background:#e5ecf9;overflow:hidden;
border-top:solid 1px #3366cc;font-weight:bold;
cursor:move;}
.dropCue{border:dashed 1px #ff0000;margin-bottom:5px;}
.emptyList{font-weight:bold;text-align:center;}
.centered{margin:auto;}
.templates{visibility:hidden;}
</style>
</head>
<body>
<form id="form1" runat="server">
<div class="main">
<!-- Left Area -->
<div id="leftArea" class="list1">
<div id="content1" class="item">
<div id="content1Handle" class="itemHandle">Content 1</div>
<div class="itemContent">
<asp:Login ID="myLogin" runat="server"
CssClass="centered"></asp:Login>
</div>
</div>
<div id="content2" class="item">
<div id="content2Handle" class="itemHandle">Content 2</div>
<div class="itemContent">
<asp:TextBox ID="myTextBox" runat="server"></asp:TextBox>
<asp:Button ID="myButton" runat="server"
Text="ClickMe" />
</div>
</div>
</div>
<!-- Right Area -->
<div id="rightArea" class="list2">
<div id="content3" class="item">
<div id="content3Handle" class="itemHandle">Content 3</div>
<div class="itemContent">
<asp:Calendar ID="myCalendar" runat="server"
CssClass="centered"></asp:Calendar>
</div>
</div>
</div>
<!-- Hide template elements -->
<div class="templates">
<!-- DropCue Template -->
<div id="dropCueTemplate" class="dropCue"></div>
<!-- Empty Template -->
<div id="emptyTemplate" class="emptyList">Drop content here.</div>
</div>
</div>
</form>
<script type="text/xml-script">
<page>
<components>
<!-- Left Area -->
<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>
<!-- Right Area -->
<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>
<!-- Draggable items -->
<control id="content1">
<behaviors>
<draggableListItem handle="content1Handle" />
</behaviors>
</control>
<control id="content2">
<behaviors>
<draggableListItem handle="content2Handle" />
</behaviors>
</control>
<control id="content3">
<behaviors>
<draggableListItem handle="content3Handle" />
</behaviors>
</control>
</components>
</page>
</script>
</body>
</html>