Flex 中要想控制Tree组件内,节点的拖动位置,需要进行如下操作。
1. 要想真正限制树节点拖动位置,使用简单的拖动事件是不行的,需要重写Tree树组件类。
2. 然后重写Tree树组件的:dragDropHandler 方法。
3. 在使用时,使用重写的树组件。
如下是一个实例:
第一步:重写Tree树组件类:
package zwn {
import mx.collections.ICollectionView;
import mx.collections.IViewCursor;
import mx.controls.Tree;
import mx.core.mx_internal;
import mx.events.DragEvent;
import mx.managers.DragManager;
use namespace mx_internal; //命名空间
public class ZwnTree extends Tree {
//_dropData 直接从继承的 Tree类中拿来用的
public function ZwnTree() {
super();
}
/**
* @private
* Returns the stack of parents from a child item.
*/
private function getParentStack(item:Object):Array {
var stack:Array = [];
if (item == null)
return stack;
var parent:* = getParentItem(item);
while (parent) {
stack.push(parent);
parent = getParentItem(parent);
}
return stack;
}
override protected function dragDropHandler(event:DragEvent):void {
// if we're moving to ourselves, we need to treat it specially and check for "parent"
// problems where we could recurse forever.
if (event.dragSource.hasFormat("treeItems")) {
var items:Array = event.dragSource.dataForFormat("treeItems") as Array;
var i:int;
var n:int;
if (event.action == DragManager.MOVE && dragMoveEnabled) {
if (event.dragInitiator == this) {
// If we're dropping onto ourselves or a child of a descendant then dont actually drop
calculateDropIndex(event);
// If we did start this drag op then we need to remove first
var index:int;
var parent:*;
var parentItem:*;
var dropIndex:int = _dropData.index;
// 获得 拖动目标 项的父节点 。 get ancestors of the drop target item
var dropParentStack:Array = getParentStack(_dropData.parent);
dropParentStack.unshift(_dropData.parent); //将父节点添加到数组的开头
n = items.length;
for (i = 0;i < n;i++) {
parent = getParentItem(items[i]); //获得父节点
index = getChildIndexInParent(parent,items[i]); //获得父节点的索引号
//check ancestors of the dropTarget if the item matches, we're invalid
//确定 拖动目标 的父节点
//
var item:* = items[i];
var itemName:String = item.localName().toString(); //
var targetParent:*;
for each (parentItem in dropParentStack) {
//we dont want to drop into one of our own sets of children
// 不能把节点放到自身的子节点下面
if (items[i] === parentItem)
return;
//zwn 上
if (parentItem) {
var targetParentName:String = parentItem.localName().toString();
if (itemName == "section" && targetParentName == "chapter") {
targetParent = parentItem;
break;
}
if (itemName == "chapter" && targetParentName == "content") {
targetParent = parentItem;
break;
}
}
//zwn 下
}
//we remove before we add due to the behavior
//of structures with parent pointers like e4x
if (targetParent) { //zwn
removeChildItem(parent,items[i],index);
//is the removed item before the drop location?
// then we need to shift the dropIndex accordingly
if (parent == _dropData.parent && index < _dropData.index)
dropIndex--;
addChildItem(targetParent,items[i],dropIndex);
}
}
return;
}
}
// If not dropping onto ourselves, then add the
// items here if it's a copy operation.
// If it's a move operation (and not on ourselves), then they
// are added in dragCompleteHandler and are removed from
// the source's dragCompleteHandler. We do both in dragCompleteHandler
// because in order to be re-parented, they must be removed from their
// original source FIRST. This means our code isn't coupled fantastically
// as dragCompleteHandler must get the destination tree and
// cast it to a Tree.
/*
if (event.action == DragManager.COPY) {
if (!dataProvider) {
// Create an empty collection to drop items into.
dataProvider = [];
validateNow();
}
n = items.length;
for (i = 0;i < n;i++) {
var item:Object = copyItemWithUID(items[i]);
addChildItem(_dropData.parent,item,_dropData.index);
}
}
*/
lastDragEvent = null;
}
}
/**
* @private
* Finds the index distance between a parent and child
*/
private function getChildIndexInParent(parent:Object,child:Object):int {
var index:int = 0;
if (!parent) {
var cursor:IViewCursor = ICollectionView(iterator.view).createCursor();
while (!cursor.afterLast) {
if (child === cursor.current)
break;
index++;
cursor.moveNext();
}
} else {
if (parent != null && _dataDescriptor.isBranch(parent,iterator.view) && _dataDescriptor.hasChildren(parent,
iterator.view)) {
var children:ICollectionView = getChildren(parent,iterator.view);
if (children.contains(child)) {
cursor = children.createCursor();
while (!cursor.afterLast) {
if (child === cursor.current)
break;
cursor.moveNext();
index++;
}
} else {
//throw new Error("Parent item does not contain specified child: " + itemToUID(child));
}
}
}
return index;
}
}
}
第二步:使用 ZwnTree 类
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" fontSize="15"
xmlns:zwn="zwn.*">
<mx:Script>
<![CDATA[
import mx.events.DragEvent;
import mx.managers.DragManager;
import mx.core.DragSource;
import mx.events.DragEvent;
private function dropDrag(event:DragEvent):void {
tree.hideDropFeedback(event); //取消默认画线
}
]]>
</mx:Script>
<mx:XMLListCollection id="xmlColl" source="{xmlList}"/>
<mx:XMLList id="xmlList" xmlns="">
<lecture name="潭浩强" sex="男" age="55"
position="教授" isBranch="true"/>
<content name="全局信息" isBranch="true">
<chapter id="01" name="普通Flash" isBranch="true">
<section id="0101" name="Flash1" type="SWF"/>
<section id="0102" name="Flash2" type="SWF"/>
</chapter>
<chapter id="01" name="相册" isBranch="true">
<section id="0104" name="相册1" type="Album"/>
<section id="0104" name="相册2" type="Album"/>
</chapter>
<chapter id="02" name="视频" isBranch="true">
<section id="0201" name="我相信MV" type="FLV"/>
<section id="0202" name="跳伞" type="FLV"/>
</chapter>
<chapter id="03" name="wulei's ex" isBranch="true">
<section id="0301" name="测验1" type="QTI"/>
<section id="0302" name="测验2" type="QTI"/>
</chapter>
<chapter id="04" name="音画同步" isBranch="true">
<section id="0401" name="音画同步01" type="VSync"/>
<section id="0402" name="音画同步04" type="VSync"/>
</chapter>
</content>
</mx:XMLList>
<zwn:ZwnTree id="tree" labelField="@name" width="300"
height="100%" dragEnabled="true" dropEnabled="true"
dragMoveEnabled="true" dragDrop="dropDrag(event);" dataProvider="{xmlColl}"/>
</mx:Application>
说明:源码见附件。
分享到:
相关推荐
拖拽功能则为 Tree 提供了更丰富的交互性,让用户可以通过拖放操作来重新排列节点或移动节点到不同的位置,这在需要调整结构或分类数据的场景中非常有用。 在 Flex Tree 的拖拽操作中,主要涉及以下几个核心知识点...
在Flex CheckboxTree中,每个树节点都有一个与之关联的复选框。当用户点击复选框时,相应的树节点会被选中或取消选中。开发者可以通过监听CheckBoxTree的事件来处理这些变化,例如,当节点的选中状态改变时,更新...
flex中利用tree中的子节点与自定义组件实现的在同一页面中实现导航
总结一下,"flex拖动树形"是一个利用Flex框架中的DragManager和DropTarget实现的交互式树形控件,用户可以将树形结构中的节点从左选项框拖放到右选项框。这个特性需要对Flex组件、事件处理和数据绑定有深入理解,...
在这个特定的场景中,我们讨论的是一个Flex中的“拖拽树控件”,这是一种允许用户通过拖放操作在树形结构中添加、删除和移动节点的组件。 在Flex中,实现拖拽功能主要依赖于内置的DragManager和DropManager类。...
本教程将详细介绍如何在Flex 4.5中实现Tree组件与任意组件之间的拖放操作,特别是将树形结构的数据拖拽到DataGrid中,并获取目标位置的全部数据进行添加。 1. **Flex 4.5的DragManager和DropTarget** Flex 4.5中的...
通过阅读和分析这些代码,你可以更深入地理解如何在Flex Tree中实现快速定位功能。 总结起来,"Flex Tree快速定位树结点"是一个提高用户交互体验的功能,它通过监听用户输入并搜索匹配的树节点,然后自动展开或选择...
Flex Tree 刷新数据源后,重新打开指定节点的解决方案,不需要延迟等其他手段
Flex Tree组件是Adobe Flex框架中的一个关键元素,用于在用户界面上展示层次结构的数据。它在各种应用程序中广泛使用,特别是在需要展现具有嵌套结构的数据时,如文件系统、组织结构或者复杂的分类信息。让我们深入...
2. **Checkbox集成**:在Flex Tree中添加Checkbox,通常是为了提供多选功能。这需要自定义TreeItemRenderer,以便在每个节点上显示一个Checkbox。当用户勾选Checkbox时,表示选择了该节点。这个自定义的renderer需要...
在这个特定的场景中,我们关注的是在Flex Tree中集成复选框功能,这为用户提供了一种直观的方式来选择或操作树形结构中的多个节点。让我们深入探讨这个主题,了解如何实现Flex Tree复选框以及其与父目录状态之间的...
在这个场景中,我们关注的是如何在Flex4的Tree控件中添加CheckBox,以便用户可以多选树形结构中的节点。 Tree控件在Flex中用于展示层次结构的数据,它允许用户展开和折叠节点,查看和导航数据结构。在很多情况下,...
本主题将深入探讨如何在Flex Tree中实现自定义节点图标,以及与之相关的源码分析。 1. **自定义节点图标的意义** - 节点图标可以增强用户对树结构的理解,通过图标直观地传达节点类型或状态信息。 - 图标可以是...
在Flex开发中,Tree组件和Checkbox控件的结合使用是一个常见的需求,特别是在构建具有层级结构并需要用户进行多选操作的界面时。本插件专为此目的设计,它允许用户在树形结构中通过复选框来选择或取消选择节点,从而...
在IT行业中,Flex Tree是一种常用于数据展示和交互的组件,尤其在构建用户界面时,它能够以树形结构清晰地展示层次数据。配合Checkbox(复选框)功能,可以提供用户选择或过滤数据的便利操作。"Flex Tree + Checkbox...
在Flex布局中,节点通常指的是容器内的子元素,这些子元素可以灵活地调整自己的尺寸和位置,以适应不同的屏幕尺寸和设备。画线是指在这些Flex节点之间添加线条来表示某种关系或者增强视觉效果。这可能包括边框、分割...
在Flex开发中,"flex checkboxtree复选树形下拉框"是一种常见的用户界面组件,它结合了树形结构和复选框的功能,允许用户在层次结构中进行多选操作。这种组件通常用于数据筛选、配置设置或者层级分类的选择场景。在...
在Flex编程中,Tree控件是一种常用的用户界面元素,它用于显示层次结构的数据。这个“flex tree控件”主题主要关注如何自定义Tree控件的外观,特别是如何去掉默认的图标并添加线连接来增强视觉效果。下面我们将深入...
Flex Tree是Adobe Flex框架中的一个组件,用于展示层次结构数据,如文件系统、组织结构或任何其他具有层级关系的数据。本教程将深入讲解Flex Tree组件的使用方法和关键概念,帮助开发者更好地理解和应用这一功能强大...