Flex Tree 限制只能同级拖动 获得拖动前后节点信息

自定义树控件
package 
{
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.controls.Tree;
import mx.controls.treeClasses.TreeItemRenderer;
import mx.events.DragEvent;
import mx.managers.DragManager;
import mx.rpc.events.ResultEvent;

/**
* 自定义树控件
* 此树控件只能同级移动,树有根节点,可以获得拖动前后的节点信息
* @author yjq
*
*/
public class YJQTree extends Tree
{
public function YJQTree()
{
super();
}


/**
* 拖动结束函数 (起始节点信息:Array,起始节点信息:Array)
* 外部调用设置此函数以便获得拖动后的节点的 拖动前和拖动后的信息
*
*/
public var dragCompleteFunc:Function;

/**
*拖动起始节点信息
*/
private var startNodes:Array;

private var draggedItems:Array;


private function get yjqDataProvider():Object
{
return dataProvider;
}


/**
* 拖动放置时的事件
* @param event
*
*/
override protected function dragDropHandler(event:DragEvent):void
{
var tree:Tree = event.target as Tree;//树控件
var draggedFormat:String = event.dragSource.formats[0];
draggedItems = event.dragSource.dataForFormat(draggedFormat) as Array;
startNodes = [];
var parent:Object = null;
var dropIndx:int = tree.calculateDropIndex(event);
if(showRoot&&dropIndx == 0)//如果是显示根节点且目标是被拖到根节点,则不符合规则
{
event.preventDefault();
return ;
}
for each(var draggedItem:Object in draggedItems)
{
var nodeInfo :YJQTreeNodeInfo = new YJQTreeNodeInfo();
getDragNodeInfo(draggedItem,yjqDataProvider,nodeInfo);
if(parent==null)
{
parent = nodeInfo.parent;
}
if(nodeInfo.parent == null)//不允许拖动根节点
{
event.preventDefault();
return ;
}
if(parent!=nodeInfo.parent)//不允许一起拖动动不同层次的节点
{
event.preventDefault();
return ;
}
startNodes.push(nodeInfo);
}
super.dragDropHandler(event);
}



/**
* 拖动完成事件
* @param event
*
*/
override protected function dragCompleteHandler(event:DragEvent):void
{
if(startNodes==null||startNodes.length==0)
{
super.dragCompleteHandler(event);
return ;
}
var endNodes:Array = [];
var parent:Object = null;
for each(var draggedItem:* in draggedItems)
{
var nodeInfo :YJQTreeNodeInfo = new YJQTreeNodeInfo();
getDragNodeInfo(draggedItem,yjqDataProvider,nodeInfo);
endNodes.push(nodeInfo);
}

var endNodeInfo:YJQTreeNodeInfo = endNodes[0];
var startNodeInfo:YJQTreeNodeInfo = startNodes[0];
if(endNodeInfo.level == startNodeInfo.level)//拖动在同一级的话则接受拖动
{
//DragManager.acceptDragDrop(
if(dragCompleteFunc!=null)
dragCompleteFunc(startNodes,endNodes);
}
else//拖动在不同级的话,则不允许拖动
{
recoveryNodes(startNodes,endNodes);
}
super.dragCompleteHandler(event);
}

/**
* 恢复节点到以前的状态
* @param startNodesInfo
* @param endNodesInfo
*
*/
private function recoveryNodes(startNodesInfo:Array,endNodesInfo:Array):void
{
//删除现在的节点
for each(var nodeInfo:YJQTreeNodeInfo in endNodesInfo)
{
if(nodeInfo.parent is Array||nodeInfo.parent is ArrayCollection)
{
delFromArray(nodeInfo.node,nodeInfo.parent);
continue;
}
delFromArray(nodeInfo.node,nodeInfo.parent.children);
}
//恢复以前节点
for each(nodeInfo in startNodesInfo)
{
addToArray(nodeInfo.node,nodeInfo.index,nodeInfo.parent.children);
}

var opened :Boolean= isItemOpen(nodeInfo.parent);
expandItem(nodeInfo.parent,!opened);
expandItem(nodeInfo.parent,opened);

}

/**
* 从数组中删除一个元素
* @param obj
* @param arr array/arraycollection
*
*/
private function delFromArray(obj:*,arr:*):void
{
if(obj==null)
return ;
for(var i:int =0;i<arr.length;i++)
{
var item:* = arr[i];
if(item == obj)
{
break;
}
}
if(arr is ArrayCollection)
{
(arr as ArrayCollection).removeItemAt(i);
return ;
}
for(var j:int = i;j<arr.length-1;j++)
{
arr[j]=arr[j+1];
}
arr.pop();
}

/**
* 向数据中指定位置添加一个元素
* @param obj
* @param arr array/arraycollection
*
*/
private function addToArray(obj:*,indx:int,arr:*):void
{
if(obj==null||indx>arr.length||indx<0)
return ;
if(arr is ArrayCollection)
{
(arr as ArrayCollection).addItemAt(obj,indx);
return ;
}
arr.push(null);
for(var i:int = arr.length-1;i>indx;i--)
{
arr[i]= arr[i-1];
}
arr[indx] = obj;
}


/**
* 得到节点所在树的信息
* @param dragItem
* @param datasouce
* @param nodeInfo
*
*/
private function getDragNodeInfo(dragItem:Object,datasouce:Object,nodeInfo:YJQTreeNodeInfo):Boolean
{
var relsult:Boolean = false;
var firstLevel:Boolean = false;
var fors:*;
if(datasouce is Array||datasouce is ArrayCollection)
{
firstLevel=true;
fors = datasouce;
}
else if(("children" in datasouce)==false)
return false;
else
fors = datasouce.children;
for(var i:int = 0 ;i<fors.length;i++)
{
var child:Object = fors[i];
if(child == dragItem)
{
nodeInfo.index = i;
nodeInfo.parent = datasouce;
nodeInfo.level++;
nodeInfo.node = child;
return true;
}
relsult = getDragNodeInfo(dragItem,child,nodeInfo);
if(relsult)
{
nodeInfo.level++;
return true;
}
}
return false;

}




}



}
自定义节点信息
package
{
/**
* 自定义树节点信息
* @author yjq
*
*/
public class YJQTreeNodeInfo
{
/**
*父节点
*/
public var parent:Object;

/**
*节点在父节点下的索引号
*/
public var index:int = -1;

/**
*节点值
*/
public var node:Object;

/**
*节点所在层次
*/
public var level:int = -1;

}
}



原文地址:https://www.cnblogs.com/yixinliu/p/2351037.html