`

flex Tree中的拖放

    博客分类:
  • flex
阅读更多

Tree 中的拖放 第一部分

这篇文章是关于如何放Tree节点——或者更确切地说是如何拖放Tree节点的。
因为这是一个有点复杂的主题而blog的文章不应该长达几页,所以我将这个主题分成了几篇文章。我将会讲述在一个Tree控件内的拖放,从一个Tree控件到其他地方的拖放,以及从其他地方到一个Tree控件的拖放。
如果你正在使用一个Tree控件那么你肯定已经确定了使用哪一种类型的数据:XMLListCollection 或者 ArrayCollection(请看Tree 控件的DataProviders,(这篇我已经翻译过了,译注)).不管你使用哪一种Tree的结构都是分等级的。这对XML来说非常理想,而对于ArrayCollections你则需要使用包含ArrayCollections子节点的ArrayCollections来提供这种结构。
我之所以提到这些,是为了让那些以前没有使用过Tree控件的人熟悉一下如何为Tree提供数据。由于我相信多数程序都使用XML作为Tree的数据,所以这些拖放的例子也将使用XML。
在一个Tree内进行拖放
让一个Tree控件允许用户进行拖拽节点来重新排列是非常简单的事情。想一下这样一个文件浏览器,你可以将文件从一个文件夹拖拽到另一个文件夹中。
这样设定你的Tree控件:

 ···程序代码

<mx:Tree x="162" y="122" width="279" height="278"
       dataProvider="{treeDataList}"
       labelField="@label"
dragEnabled="true"
       dragMoveEnabled="true"
       dropEnabled="true"
       />

通过将dragMoveEnabled 和 dropEnabled 设定为 true,Tree中的节点就可以被拖拽了。
DragSource
在讨论拖放之前,理解DragSource是很重要的。在拖拽事件处理器的事件(mx.events.DragEvent)参数中提供了一个该类的实例。DragSource包含了很多东西,其中包括对拖拽操作的启动控制,数据的格式以及通过格式对数据的访问。
比如,如果你从一个目录里拖拽了一个条目,DragSource的数据可能是该条目的一个图像以及关于该条目的数据。所以DragSource有两种格式:图像和数据项(items)。
在下面的这些例子中你将会看到 ”items” 被用来作为格式的名字来访问DragSource中的数据。像Tree,DataGrid,以及List等Flex控件在自动创建一个DragSource的时候,都是用 ”item” 作为格式的名字的。
拖拽到一个Tree
使用 dropEnabled="true" 可以使得Tree控件接收拖拽事件并且监听下面的事件:

 ···程序代码

<mx:Tree x="162" y="122" width="279" height="278"
       dataProvider="{treeDataList}"
       labelField="@label"
       dropEnabled="true"
dragEnter="onDragEnter(event)"
       dragOver="onDragOver(event)"
       dragDrop="onDragDrop(event)"
       />

当鼠标将对象拖拽到Tree上时会分派dragEnter事件。Tree必须确定是否接受该拖拽。这是因为设定了dragEnabled并不是说所有的拖拽都会被接受。此外,dragEnter事件还可以利用事件中的信息——比如拖拽的启动控制(叫做dragInitiator)或者被拖拽的数据。
这里有一个简单的dragEnter事件处理器:

 ···程序代码

private function onDragEnter( event:DragEvent ) : void
        {
              DragManager.acceptDragDrop(UIComponent(event.currentTarget));
         }

当鼠标将对象拖拽进入Tree的框架内的时候会分派dragOver事件。你可以忽略这个事件,但是你也可以使用它来为用户提供反馈。比如,可以将鼠标下的节点设置为高亮。你甚至可以查看正在被拖拽的节点和鼠标下节点的数据来判断这次拖拽是否被允许。例如,如果一个Tree是关于汽车经销的,现在你将一辆跑车拖到Tree上面,如果将跑车拖到了小型货车目录上面的话你可以改变拖拽的鼠标指针来通知用户那里不允许进行此次拖拽。
下面是一个dragOver事件触发器,它判定哪一个节点在鼠标下并给出相应信息:

 ···程序代码

private function onDragOver( event:DragEvent ) : void
      {
// r is the visible index in the tree
           var dropTarget:Tree = Tree(event.currentTarget);
           var r:int = dropTarget.calculateDropIndex(event);
           tree.selectedIndex = r;
// retrieving the newly selected node, you can examine it and decide to tell
           // the user the drop is invalid by changing the feedback.
           var node:XML = tree.selectedItem as XML;
           if( node.@type == "minivan" ) {
               DragManager.showFeedback(DragManager.NONE);
               return;
           }
// the type of drop - copy, link, or move can be reflected in the feedback as well.
           // Here the control and shift keys determine that action.
           if (event.ctrlKey)
               DragManager.showFeedback(DragManager.COPY);
           else if (event.shiftKey)
               DragManager.showFeedback(DragManager.LINK);
           else {
              DragManager.showFeedback(DragManager.MOVE);
           }
      }

当放开鼠标的时候会分派dragDrop事件。Tree也可以忽略这个事件(因为用户可能错误地在小型货车目录上放开了鼠标),但是这个事件将被拖拽的数据复制给Tree。你可以利用全部或部分数据,也可以不利用。你可以创建节点或者替换节点甚至创建新的分支——这些取决于你的程序设计。

 ···程序代码

private function onDragDrop( event:DragEvent ) : void
{
       var ds:DragSource = event.dragSource;
       var dropTarget:Tree = Tree(event.currentTarget);
// retrieve the data associated with the "items" format. This will be the data that
       // the dragInitiator has copied into the DragSource.
       var items:Array = ds.dataForFormat("items") as Array;
// determine where in the tree the drop occurs and select that node by the index; followed by
       // retrieving the node itself.
       var r:int = tree.calculateDropIndex(event);
       tree.selectedIndex = r;
       var node:XML = tree.selectedItem as XML;
       var p:*;
// if the selected node has children (it is type==city),
       // then add the items at the beginning
       if( tree.dataDescriptor.hasChildren(node) ) {
             p = node;
             r = 0;
       } else {
             p = node.parent();
       }
// taking all of the items in the DragSouce, insert them into the
       // tree using parent p.
       for(var i:Number=0; i < items.length; i++) {
             var insert:XML = <node />;
             insert.@label = items[i];
             insert.@type = "restaurant";
             tree.dataDescriptor.addChildAt(p, insert, r+i);
       }
}

dragComplete事件是在拖拽启动器(例如:一个列表)中注册的,当拖拽操作结束的时候会调用它 —— 在拖拽被接受并处理时,或拖拽被拒绝时,或者在用户将对象拖拽到一个不允许拖拽的区域中时。
在下面的例子中,所作的唯一一件事情就是清除dragOver 和dragDrop 操作在tree中做的选择。
private function onDragComplete( event:DragEvent ) : void
{
     tree.selectedIndex = -1;
}
总结
将信息拖拽到一个Tree控件时需要确定该拖拽是否会被接受。这个可以在dragEnter事件的开始检测,也可以在dragOver事件中被拖拽对象移动到Tree控件上面时动态地检测。


Tree 中的拖放 第二部分

在 Tree 中的拖放第一部分(译注:此文我已经翻译)中我讲述了如何在一个Tree控件内拖拽元素以及如何将元素从Tree控件外部拖拽到Tree中。这篇文章我会讲述如何从Tree中拖拽元素(到其它的控件)。
运行示例
要从一个Tree中拖拽元素你需要将Tree的dropEnabled属性设定为false并且将它的dragEnabled属性设定为true:

 ···程序代码

<mx:Tree x="34" y="81" width="181" height="189"
     dataProvider="{treeData.node}"
     labelField="@label"
dropEnabled="false"
     dragEnabled="true"
     dragMoveEnabled="false"
/>

在这个例子中,假定Tree中的数据是美国的各州,州中的城市以及城市中的饭店。进一步地,我们要拖拽到的目标是一个这样定义的DataGrid:

 ···程序代码

<mx:DataGrid x="291" y="81" height="189"
     dataProvider="{dataGridProvider}"
     dragEnter="onDragEnter(event)"
     dragOver="onDragOver(event)"
     dragDrop="onGridDragDrop(event)"
     dragExit="onDragExit(event)">
    <mx:columns>
        <mx:DataGridColumn headerText="Label" dataField="label"/>
        <mx:DataGridColumn headerText="Type" dataField="type"/>
    </mx:columns>
</mx:DataGrid>

在所有的拖放操作中,那些事件处理器是操作成功的关键所在。
DragEnter事件(DataGrid中的)决定了拖拽是否可以进行。在这个例子中,只有那些表示饭店的节点可以被DataGrid接受。一个典型的tree节点会像这样:

 ···程序代码

<node label="Lobster Pot" type="restaurant" />

其中@type属性可以被用决定被拖拽的节点是否可以被接受。DragEnter事件可以这样定义:

 ···程序代码

private function onDragEnter( event:DragEvent ) : void
{
     if( event.dragInitiator is Tree ) {
         var ds:DragSource = event.dragSource;
         if( !ds.hasFormat("treeItems") ) return; // no useful data
         var items:Array = ds.dataForFormat("treeItems") as Array;
         for(var i:Number=0; i < items.length; i++) {
             var item:XML = XML(items[i]);
if( item.@type != "restaurant" ) return; // not what we want
         }   
     }
     // if the tree passes or the dragInitiator is not a tree, accept the drop
     DragManager.acceptDragDrop(UIComponent(event.currentTarget));
}

如果开始拖拽操作的是一个Tree控件,dragSource就会检查它是否包含 "treeItems" 以及这些元素的 @type 是否为  "restaurant"。如果检测结果为成功,则DataGrid(即event.currentTarget)将会接受这次拖拽.
当用户移动拖拽的元素时dragOver事件将处理其反馈(feedback):

 ···程序代码

private function onDragOver( event:DragEvent ) : void
{
     if( event.dragInitiator is Tree ) {
         DragManager.showFeedback(DragManager.COPY);
     } else {
         if (event.ctrlKey)
             DragManager.showFeedback(DragManager.COPY);
         else if (event.shiftKey)
             DragManager.showFeedback(DragManager.LINK);
         else {
             DragManager.showFeedback(DragManager.MOVE);
         }
     }
}

当dragInitiator是Tree的时候,反馈总是被设定为COPY。当然,你也可以将反馈设定为任何你喜欢的东西,但是在这个例子中反馈是一个copy操作,这样Tree中的信息就不会被删除。
当鼠标移动到DataGrid上并松开时会触发DataGrid的dragDrop事件。数据将会被检查并添加到DataGrid中。

 ···程序代码

private function onGridDragDrop( event:DragEvent ) : void
{
     var ds:DragSource = event.dragSource;
     var dropTarget:DataGrid = DataGrid(event.currentTarget);
     var arr:Array;
     if( ds.hasFormat("items") ) {
         arr = ds.dataForFormat("items") as Array;
     } else if( ds.hasFormat("treeItems") ) {
arr = ds.dataForFormat("treeItems") as Array;
     }
     for(var i:Number=0; i < arr.length; i++) {
         var node:XML = XML(arr[i]);
         var item:Object = new Object();
         item.label = node.@label;
         item.type = node.@type;
         dataGridProvider.addItem(item);
     }
     onDragExit(event);
}

当一个控件将拖拽操作初始化完毕的时候,dragSource就会被检查然后treeitems会被取出。接下来会创建一个循环来将新的元素添加到DataGrid中。最后,会调用onDragExit方法:

 ···程序代码

private function onDragExit( event:DragEvent ) : void
{
     var dropTarget:ListBase=ListBase(event.currentTarget);
     dropTarget.hideDropFeedback(event);
}

这个函数只是用来确保可视化的反馈被删除。
从Tree中拖拽(到其他控件)非常简单——只需要检查包含"treeItems"的dragSource并且依照程序中的行为来处理他们。在这个例子中,只有 "restaurant" 类型的tree节电被允许拖拽到DataGrid中并且在开始的DragEnter方法中对其进行处理,这样在以后的步骤里就不用再次检测了。

< type=text/javascript> < src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type=text/javascript> <>window.google_render_ad();

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/cjy37/archive/2008/11/24/3363286.aspx

分享到:
评论

相关推荐

    flex中 Tree树节点内部拖动实例(此实例限制了什么节点可以拖动及拖动到什么位置)

    这个实例涉及的是在Flex中的Tree组件实现节点的内部拖放功能,这对于创建交互式用户界面,尤其是数据层级结构的展示非常有用。在本文中,我们将详细探讨如何在Flex的Tree组件中实现节点的拖放操作,并且限制可拖动的...

    Flex3组件拖放教程

    通过拖放操作,用户能够选择一个对象(例如`List`控件或Flex中的`Image`控件),并将其拖动至另一个组件(容器)中,最终将该对象添加到目标组件内。 #### 二、关于拖放操作 拖放操作主要包括三个阶段:初始化、...

    Flex tree的用法

    Flex Tree组件是Adobe Flex框架中的一个关键元素,用于在用户界面上展示层次结构的数据。它在各种应用程序中广泛使用,特别是在需要展现具有嵌套结构的数据时,如文件系统、组织结构或者复杂的分类信息。让我们深入...

    flex tree 教程二

    Flex Tree是Adobe Flex框架中的一个组件,用于展示层次结构数据,如文件系统、组织结构或任何其他具有层级关系的数据。本教程将深入讲解Flex Tree组件的使用方法和关键概念,帮助开发者更好地理解和应用这一功能强大...

    flex tree控件

    在Flex编程中,Tree控件是一种常用的用户界面元素,它用于显示层次结构的数据。这个“flex tree控件”主题主要关注如何自定义Tree控件的外观,特别是如何去掉默认的图标并添加线连接来增强视觉效果。下面我们将深入...

    flex tree 拖拽

    在 Flex 应用中,Tree 控件经常用于展示具有层级关系的数据,例如文件系统、组织结构或者菜单等。拖拽功能则为 Tree 提供了更丰富的交互性,让用户可以通过拖放操作来重新排列节点或移动节点到不同的位置,这在需要...

    flex tree的简单使用

    在Flex编程中,Tree组件是一种常用的用户界面元素,它用于展示层次结构的数据。"flex tree的简单使用"这个主题将引导我们了解如何在Flex应用程序中有效地利用Tree组件来展示和操作树状数据。 首先,我们要知道Tree...

    拖拽Tree中结点的例子

    在本文中,我们将深入探讨如何实现“拖拽Tree中结点的例子”,这主要涉及使用Adobe Flex的树组件(Tree)来实现节点的拖放(Drag and Drop)功能。Flex是一种基于ActionScript 3.0的开源框架,用于构建富互联网应用...

    flex4Tree组件分层显示数据示例

    在提供的源码中,你可能还会看到有关如何设置Tree组件的样式和属性的部分,比如`indentation`用于控制节点间的缩进,`showRoot`决定是否显示根节点,以及`dragDrop`功能的实现,允许用户通过拖放操作重新排列节点。...

    Flex 4.5 实现tree拖拽到任意组建

    本教程将详细介绍如何在Flex 4.5中实现Tree组件与任意组件之间的拖放操作,特别是将树形结构的数据拖拽到DataGrid中,并获取目标位置的全部数据进行添加。 1. **Flex 4.5的DragManager和DropTarget** Flex 4.5中的...

    flex grade tree 小案例

    在本小案例中,我们关注的是使用Flex技术构建一个分级树视图,即"flex grade tree"。这个项目并未涉及到数据库交互,而是专注于展示如何利用各种组件来创建一个功能性的树形结构。以下是对每个文件的详细解释: 1. ...

    Flex基础培训-6-拖放与过滤

    - **初始化**:在Flex中,对于基于`List`的组件(如`List`, `Tree`, `DataGrid`等),用户通过点击并拖拽特定项来启动拖放操作。被拖拽的组件被称为“拖动发起者”。 - **拖动**:在此阶段,用户正在移动某个项。...

    flex 拖拽功能 中文文档

    Flex框架提供了一套强大的机制用于实现拖放(drag and drop)功能,这在用户界面设计中极为常见,特别是在构建高度交互性的应用时。本文旨在深入探讨Flex中的拖拽功能,包括其工作原理、关键概念、以及如何在实际...

    flex拖动树形

    在本案例中,我们关注的是一个特定的实现——"flex拖动树形",这是一种允许用户通过拖放操作在两个区域之间移动节点的自定义树形控件。 拖放功能是人机交互中常见的一种交互模式,用于在界面上移动元素,常用于文件...

    Flex4中文帮助文档

    - **Design View**:可视化的界面设计工具,允许开发者通过拖放组件来构建用户界面。 - **Source View**:代码编辑视图,用于编写MXML和ActionScript代码。 - **调试器**:强大的调试工具,包括断点、变量监视、...

    Flex开源项目

    11. **Flex Drag-n-Drop Library**: 一个拖放库,简化了Flex中的拖放操作实现。 12. **birdeye**: 大型数据可视化项目,包括关系分析、空间信息分析、数值分析等多个模块。 13. **antennae**: 基于Ant的Flex项目...

    flex树自定义节点图标

    - Flex Tree是基于Adobe Flex框架的组件,用于展示层次结构数据,支持拖放、展开/折叠、节点选择等多种交互操作。 - 它允许开发者自定义节点模板,以满足个性化展示的需求。 3. **自定义节点图标的方法** - 数据...

    flex自定义树形结构

    在IT行业中,尤其是在前端开发领域,`Flex`布局和`Tree`数据结构是两种非常重要的概念。本篇文章将深入探讨如何在Flex环境中自定义实现一个具备展开、收缩功能的多级目录树形结构。 首先,让我们理解`Flex`布局。...

    从头开发Flex树遇到的问题

    Tree组件在Flex中是一种显示层次数据的控件,它可以展开和折叠节点,使用户能够导航复杂的结构。开发者通常会自定义Tree组件来满足特定的业务需求,比如更改默认样式、增加交互功能或者处理复杂的数据显示逻辑。 在...

    flex 画图的代码

    在Flex编程中,"flex 画图的代码"通常指的是使用Adobe Flex框架创建图形界面,特别是涉及用户交互,如拖放功能和动态连线的场景。Flex3是Flex框架的一个版本,它提供了强大的组件库和MXML语言,使得开发富互联网应用...

Global site tag (gtag.js) - Google Analytics