针对树形菜单的相关操作,实现的大致功能如下:
1.展开所有节点
2.关闭所有节点
3.选中某个节点并展开父节点
4.添加节点
5.修改节点
6.删除节点
7.修改节点图标
7.模糊查询节点
8.同级之间的节点拖拽
效果图:
代码:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
<fx:XML id="treeData" xmlns="">
<root label="监控点">
<node id="1" label="软件园一期" icon="iconNode" pid="0">
<node id="6" pid="1" label="望海路一" icon="iconNode"/>
<node id="7" pid="1" label="观日路一" icon="iconNode"/>
</node>
<node id="2" label="软件园二期" icon="iconNode" pid="0">
<node id="8" pid="2" label="望海路二" icon="iconNode"/>
</node>
<node id="3" label="软件园三期" icon="iconNode" pid="0">
<node id="9" pid="3" label="望海路三" icon="iconNode"/>
</node>
<node id="4" label="软件园四期" icon="iconNode" pid="0">
<node id="10" pid="4" label="望海路四" icon="iconNode"/>
</node>
<node id="5" label="软件园五期" icon="iconNode" pid="0">
<node id="11" pid="5" label="望海路五" icon="iconNode"/>
</node>
</root>
</fx:XML>
</fx:Declarations>
<fx:Style>
@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";
.treeStyle{
/*去掉默认文件夹图标*/
folderClosedIcon: ClassReference(null);
folderOpenIcon: ClassReference(null);
/*去掉叶子节点图标*/
defaultLeafIcon: ClassReference(null);
/*
defaultLeafIcon 指定叶图标
disclosureClosedIcon 指定的图标旁边显示一个封闭的分支节点。默认的图标是一个黑色三角形。
disclosureOpenIcon 指定的图标旁边显示一个开放的分支节点。默认的图标是一个黑色三角形。
folderClosedIcon 关闭指定的文件夹图标的一个分支节点。
folderOpenIcon 指定打开的文件夹图标的一个分支节点。
例:三角图标修改如下代码使用即可换成自己的了:
disclosureOpenIcon:Embed(source='images/a.png');
disclosureClosedIcon:Embed(source='images/b.png');
*/
disclosureOpenIcon:Embed(source='tree_open.png');
disclosureClosedIcon:Embed(source='tree_close.png');
folderOpenIcon:Embed(source='node.png');
folderClosedIcon:Embed(source='node.png');
}
</fx:Style>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.core.DragSource;
import mx.core.UIComponent;
import mx.events.DragEvent;
import mx.managers.DragManager;
[Bindable]
[Embed(source="node_open.png")]
public var iconNode:Class;
[Bindable]
[Embed(source="node.png")]
public var uIcon:Class;
//添加在统计节点之前
protected function addBefore():void
{
var xml:XML=tree.selectedItem as XML; //转换xml
var text:String=nodeText.text; //获取文本框的值
if(xml!=null && text.length>0) {
var parent:XML=xml.parent(); //获取父xml
if(parent!=null) {
var pid:int = 0;
if(parent.hasOwnProperty("@pid")){
pid = parent.@pid;
}
var child:XML=new XML("<node id=\"\" pid=\"" + pid + "\" label=\"\" icon=\"iconNode\" />");
child.@label=text;
parent.insertChildBefore(xml,child);
} else {
Alert.show("不能选中根节点");
}
} else {
Alert.show("需要先选中节点和填入文字");
}
}
//添加在同级节点之后
protected function addAfter():void
{
var xml:XML=tree.selectedItem as XML;
var text:String=nodeText.text;
if(xml!=null && text.length>0) {
var parent:XML=xml.parent();
if(parent!=null) {
var pid:int = 0;
if(parent.hasOwnProperty("@pid")){
pid = parent.@pid;
}
var child:XML=new XML("<node id=\"\" pid=\"" + pid + "\" label=\"\" icon=\"iconNode\" />");
child.@label=text;
parent.insertChildAfter(xml,child);
} else {
Alert.show("不能选中根节点");
}
} else {
Alert.show("需要先选中节点和填入文字");
}
}
//添加子节点
protected function addSon():void
{
var xml:XML=tree.selectedItem as XML;
var text:String=nodeText.text;
if(xml!=null && text.length>0) {
var parent:XML=xml.parent();
var child:XML=new XML("<node id=\"\" pid=\"" + parent.@pid + "\" label=\"\" icon=\"iconNode\" />");
child.@label=text;
xml.appendChild(child);
tree.expandChildrenOf(xml,true);
} else {
Alert.show("需要先选中节点和填入文字");
}
}
//修改节点
protected function editNode():void
{
var xml:XML=tree.selectedItem as XML;
var text:String=nodeText.text;
if(xml!=null && text.length>0) {
xml.@label=text;
} else {
Alert.show("需要先选中节点和填入文字");
}
}
//删除节点
protected function deleteNode():void
{
var xml:XML=tree.selectedItem as XML;
if(xml!=null) {
var list:Array=tree.selectedItems as Array;
for(var k:int=0;k<list.length;k++) {
xml=list[k] as XML;
var parent:XML=xml.parent();
if(parent!=null) {
var children:XMLList=parent.children();
for(var i:int=0;i<children.length();i++) {
if(children[i]==xml) {
delete children[i];
break;
}
}
} else {
Alert.show("不能选中根节点");
}
}
} else {
Alert.show("需要先选中节点");
}
}
protected function selectNode():void
{
var text:String=nodeText.text;
if(text.length>0) {
var items:Array=[];
var list:XMLList=new XMLList();
list[0]=tree.dataProvider[0];
searchItems(list,text,items);
tree.selectedItems=items;
} else {
Alert.show("输入查找的文字");
}
}
private function searchItems(list:XMLList,find:String,items:Array):void {
for(var i:int=0;i<list.length();i++) {
var one:XML=list[i];
var label:String=one.@label;
if(label!=null && label.indexOf(find)>=0) {
items.push(one);
}
searchItems(one.children(),find,items);
}
}
protected function closeAll():void{
tree.openItems=[];
}
protected function openAll():void{
//tree.expandChildrenOf(tree.selectedItem,true);
tree.openItems = treeData..node;
}
private function searchOpen():void
{
if(nodeText.text.length>0) {
var node:XMLList = treeData.child("node").child("node").(@label == nodeText.text);
expandParents(node[0]);
tree.selectedItem = node[0];
var idx:int = tree.getItemIndex(node[0]);
tree.scrollToIndex(idx);
} else {
Alert.show("输入查找的文字");
}
}
private function expandParents(node:XML):void
{
if (node && !tree.isItemOpen(node))
{
tree.expandItem(node, true);
expandParents(node.parent());
}
}
//根据关键字查找节点
private function searchNode():void {
var key:String = search.text
var list:XMLList = treeData.child("node").child("node").(@label.indexOf(key) != -1);
if(key.length == 0) {
this.closeAll();
} else {
if(list.length() == 0) {
Alert.show("没有找到相关信息!请重试","提示");
} else if(list.length() == 1) {
//展开并选中
expandParents(list[0]);
tree.selectedItem = list[0];
} else if(list.length() > 1) {
tree.dataProvider = list;
}
}
}
private function exit():void{
tree.dataProvider = treeData;
search.text = "";
}
private var flag:Boolean = true;
private function updateIcon():void{
var xml:XML=tree.selectedItem as XML;
var text:String=nodeText.text;
if(flag){
xml.@icon="uIcon";
flag = false;
}else{
xml.@icon="iconNode";
flag = true;
}
}
private var _draggedItem:XML = null;
private function onDragEnter( event:DragEvent ) : void
{
event.preventDefault();
event.currentTarget.hideDropFeedback(event);
var ds:DragSource = event.dragSource;
var items:Array = ds.dataForFormat("treeItems") as Array;
if (items != null && items.length > 0 && (items[0] is XML))
_draggedItem = items[0];
DragManager.acceptDragDrop(UIComponent(event.currentTarget));
}
private function onDragOver( event:DragEvent ) : void
{
event.preventDefault();
event.currentTarget.hideDropFeedback(event);
tree.selectedIndex = tree.calculateDropIndex(event);
var node:XML = tree.selectedItem as XML;
// restrict drag & drop to nodes within same parent
if (_draggedItem.parent() != node.parent())
{
DragManager.showFeedback(DragManager.NONE);
return;
}
DragManager.showFeedback(DragManager.MOVE);
}
private function onDragDrop( event:DragEvent ) : void
{
event.preventDefault();
event.currentTarget.hideDropFeedback(event);
tree.selectedIndex = tree.calculateDropIndex(event);
var node:XML = tree.selectedItem as XML;
var addToIndex:int = node.childIndex();
if ((_draggedItem.parent() == node.parent()) && (addToIndex != _draggedItem.childIndex()))
{
tree.dataDescriptor.removeChildAt(node.parent(), _draggedItem, _draggedItem.childIndex());
tree.dataDescriptor.addChildAt(node.parent(), _draggedItem, addToIndex);
}
}
private function onDragComplete( event:DragEvent ) : void
{
tree.selectedIndex = -1;
}
]]>
</fx:Script>
<s:layout>
<s:HorizontalLayout horizontalAlign="center" verticalAlign="middle"/>
</s:layout>
<s:BorderContainer>
<s:TextInput x="10" y="10" id="search"/>
<s:Button x="10" y="35" width="60" label="搜索" click="searchNode()"/>
<s:Button x="75" y="35" width="60" label="退出" click="exit()"/>
<mx:Tree id="tree" y="60" iconField="@icon" styleName="treeStyle"
dataProvider="{treeData}" borderVisible="false"
labelField="@label" showRoot="false" height="300" width="150"
allowMultipleSelection="false"
dragEnabled="true"
dropEnabled="true"
dragMoveEnabled="false"
dragEnter="onDragEnter(event)"
dragOver="onDragOver(event)"
dragDrop="onDragDrop(event)"
dragComplete="onDragComplete(event)"
/>
</s:BorderContainer>
<s:VGroup>
<s:TextInput id="nodeText" />
<s:Button label="添加同级之前" click="addBefore()"/>
<s:Button label="添加同级之后" click="addAfter()"/>
<s:Button label="添加子节点" click="addSon()"/>
<s:Button label="修改节点" click="editNode()"/>
<s:Button label="删除节点" click="deleteNode()"/>
<s:Button label="关闭所有" click="closeAll()"/>
<s:Button label="展开所有" click="openAll()"/>
<s:Button label="查询展开" click="searchOpen()"/>
<s:Button label="修改图标" click="updateIcon()"/>
</s:VGroup>
</s:Application>