skyeagle

 

用Atlas实现Drag And Drop功能

也许大家见过像GoogleLiveStart站点的页面效果,其中最引人注目的莫过于Drag and Drop功能了它是外面的网页内容类似与桌面窗体那样自由托放,为了不是页面太凌乱其中通过定义Zone的方式来控制各个Panel的摆放。以前我们要编写类似的代码是很难完成的,由于现在AJAX技术的兴起以及越来越多的AJAX框架极大的方便了我们编写类似的应用程序,在.NET方面Atals无疑是首选的框架,下面让我们来看一下如何通过Atlas来实现类似上面站点的Drag&Drop功能。
  首先要实现Drag&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形式。

<!-- 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>

你可以看到,我在这个静态布局的页面里面创建了两个drop zones和三个content panels。

现在我们需要一些HTML来显示一些高亮的内容当我们拖动panel的时候(the dropCueTemplate,还需要一些HTML来表明一个空的zone的状态(the empty Template).

<!-- 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>
现在我们来向页面中添加Atlas标记来使页面具有动态的行为能力。我们通过添加DragDropList behavior来使两个drop zone变成Atlas控件:
<!-- 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>

右边的区域标记跟上面的类似。在上面的代码中我们把“leftarea”<div>封装到Atlas控件中,并给她添加DragDropList behavior。它具有的数据类型为“HTML”,接受的数据类型也为“HTML”,是Vertical(垂直)的布局(另一个选择是水平的),托放的形式是移动,另一个选择是复制,假如选择的是复制那么它将复制一个Panel到你托放的区域,原来的Panel还在原处。然后再把它的dropCueTemplate和emptyTemplate与我们之前写的HTML结合起来。

 

然后标记content panel:

<!-- Draggable items -->
<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>

posted on 2006-06-17 16:42  蓝天  阅读(348)  评论(0编辑  收藏  举报

导航