Flex 3入门教程: 使用 Tree 控件

Tree控件是一个枝和叶节点分层次的机构。树中没每一个条目叫做节点,节点既可以作为枝也可以作为叶。枝节点可以包含叶或枝节点,或者为空。一个叶节点就是一个树的末梢。本快速指南包含一些开发者在使用Treecontrols经常会遇到的一些挑战。

使用XMLLISTCOLLECTION 和ARRAYCOLLECTION对象的对比。


你也许想知道,在运行时从远程或本地得来的数据被动态修改的时候,应该使用XMLListCollection对象还是ArrayCollection对象作为Tree空间的数据提供者。


如果你使用的数据源提供成形的XML,并且,你想在Tree控件中操作 XML数据。你应该使用XMLListCollection对象作为数据提供者。当使用MXML标记时,如果数据源是XMLList对象,你应该把它绑定到XMLLsitCollection对象的source属性上,然后把 XMLListCollection对象绑定到Tree控件的dataProvider属性上。

当你想要动态改变对象值时,不要使用XMLList或XML对象直接绑定到Tree控件的dataProvider属性上。当数据源是RPC(远程过程调用)服务的lastResult属性,并且你想使用XML数据,确保RPC组件的resultFormat属性被设置成e4x,当你使用e4x结果格式,最总结果就是XMLList,可以绑定在XMLListCollection对象上。

这里有一个例子。为例数据被动态改变,使用ArrayCollection对象作为Tree控件的数据提供器。当使用MXML标记时,如果你期望动态的改变Arrayl,你不应该把Array对象直接绑定到Tree控件的dataProvider属性上。作为代替,你应该绑定Array到一个ArrayCollection对象的source属性上,然后再把ArrayCollection对象绑定到Tree控件的dataProvider属性上。


当数据源是RPC(远程过程调用)服务的lastResult对象,并且RPC组件的resultFormat属性被成object,你应该使用ArrayUtil.toArray()方法来确保对象是一个Array。然后绑定到ArrayCollection对象上,就像下边的例子所示:


  1. <mx:ArrayCollection
  2. id="employeeAC"
  3. source="{ArrayUtil.toArray(employeeSrv.lastResult.employees.employee)}"/>

在运行时增加和删除叶子节点


你可以在运行时为Tree控件增加或删除叶子节点。下边的例子包含的代码来实现这种改变。这个程序使用预定义的枝和叶来初始化,表现公司部门和员工。你可以向任意枝节点增加叶节点在运行时。你也可以删除预定义的叶节点和你在运行时增加的节点。


在这个例子中的XML包含两种不同的元素名字,department和employee。Tree控件的label函数,决定根据元素的类型应该显示那些文本。它使用了E4X语法来返回department的title,或者employee的name。然后,这些语法在addEmployee()和removeEmployee()中会用到。


为了增加员工到业务部门,addEmployee()方法使用E4X语法,通过title属性的值获得业务部门的节点,并把它保存到XMLList类型的变量dept中。然后,通过调用dept.appendChild()方法向操作节点添加子结点。remove方法保存当前被选择的元素到变量node中,node的类型是XML。调用node.localName()方法确定被选择的元素是否是employee节点。如果是employee节点,删除它。


例子



  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"viewSourceURL="src/index.html">
  3. <mx:Script>
  4. <![CDATA[importmx.collections.XMLListCollection;
  5. [Bindable]
  6. privatevarcompany:XML=
  7. <list>
  8. <departmenttitle="Finance"code="200">
  9. <employeename="JohnH"/>
  10. <employeename="SamK"/>
  11. </department>
  12. <departmenttitle="Operations"code="400">
  13. <employeename="BillC"/>
  14. <employeename="JillW"/>
  15. </department>
  16. <departmenttitle="Engineering"code="300">
  17. <employeename="ErinM"/>
  18. <employeename="AnnB"/>
  19. </department>
  20. </list>;
  21. [Bindable]
  22. privatevarcompanyData:XMLListCollection=newXMLListCollection(company.department);
  23. privatefunctiontreeLabel(item:Object):String
  24. {
  25. varnode:XML=XML(item);
  26. if(node.localName()=="department")
  27. returnnode.@title;
  28. else
  29. returnnode.@name;
  30. }
  31. privatefunctionaddEmployee():void
  32. {
  33. varnewNode:XML=<employee/>;
  34. newNode.@name=empName.text;
  35. vardept:XMLList=company.department.(@title=="Operations");
  36. if(dept.length()>0){
  37. dept[0].appendChild(newNode);
  38. empName.text="";
  39. }
  40. }
  41. privatefunctionremoveEmployee():void
  42. {
  43. varnode:XML=XML(tree.selectedItem);
  44. if(node==null)return;
  45. if(node.localName()!="employee")return;
  46. varchildren:XMLList=XMLList(node.parent()).children();
  47. for(vari:Number=0;i<children.length();i++){
  48. if(children[i].@name==node.@name){
  49. deletechildren[i];
  50. }
  51. }
  52. }
  53. ]]>
  54. </mx:Script>
  55. <mx:Treeid="tree"top="72"left="50"dataProvider="{companyData}"
  56. labelFunction="treeLabel"
  57. height="224"width="179"/>
  58. <mx:HBox>
  59. <mx:Buttonlabel="AddOperationsEmployee"click="addEmployee()"/><mx:TextInputid="empName"/>
  60. </mx:HBox>
  61. <mx:Buttonlabel="RemoveSelectedEmployee"click="removeEmployee()"/>
  62. </mx:Application>

提示:可以通过右键flash查看官方源文件

在运行时添加一个空的枝节点


可以在运行时向Tree控件添加空的枝节点。下边的例子展示了通过数据提供器(data provider)API和数据描述器(data descriptor )API添加枝节点。通常,添加枝节点的首选途径是通过数据提供器(data provider)API。


addEmptyBranthDP()方法通过数据提供器API向使用XML数据提供器的Tree组件增加一个空节点,这个方法为新节点创建一个XML类型的变量,并且设置这个节点的isBranch属性为true来创建一个枝节点。然后这个方法调用Tree控件的dataProvider.addItemAt()方法来向Tree控件的数据提供器增加新的元素。


addEmptyBranchDP2()方法通过数据提供器API向使用对象数据提供器的Tree组件增加一个空节点,这个方法使用children属性创建一个新的对象,使用children属性能够确保isBranch()方法返回true。然后,这个方法调用Tree控件的dataProvider.addItemAt()方法来向Tree控件的数据提供器增加新的对象。


addEmptyBranchDD()方法通过数据描述器(data descripter)API。这个方法创建一个XML类型的变量,并且设置isBranch属性为true来创建一个枝节点。然后,这个方法调用Tree控件的dataDescriptor.addChildAt()方法来向Tree控件的数据描述器添加一个新的子节点。


例子


  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"viewSourceURL="src/index.html"><mx:Script>
  3. <![CDATA[
  4. [Bindable]
  5. privatevardataX:XML=
  6. <itemlabel="Top">
  7. <itemlabel="ChildOne"/>
  8. <itemlabel="ChildTwo"/>
  9. </item>;
  10. [Bindable]
  11. privatevardataObj:Object=
  12. [{label:"Top",children:
  13. [
  14. {label:"ChildOne"},{label:"ChildTwo"}
  15. ]
  16. }];
  17. //AddingabranchbygoingthroughtheTreecontrol'sdataProvider.Thisis
  18. //thepreferredmethod.
  19. //TogglingtheisBranchattributetotruecausesDefaultDataDescriptor.isBranch()
  20. //toreturntrueandtheTreetreatsthenodeasabranch.
  21. privatefunctionaddEmptyBranchDP():void
  22. {
  23. varnewNode:XML=<itemlabel='Middle'isBranch="true"></item>;
  24. xmlBound2Tree.dataProvider.addItemAt(newNode,1);
  25. }
  26. //Foranobjectgraph,thekeypointisthatthechildrenpropertyneedstobedefined,
  27. //evenifitisempty.
  28. //ThiscausesisBranch()toreturntrueandtheTreetreatsthenewnodeasabranch.
  29. privatefunctionaddEmptyBranchDP2():void
  30. {
  31. varnewObj:Object={label:"Middle",children:[]};
  32. objGraphBound2Tree.dataProvider.addItemAt(newObj,1);
  33. }
  34. //AddingabranchbygoingthroughtheTreecontrol'sdataDescriptor.
  35. privatefunctionaddEmptyBranchDD():void
  36. {
  37. varnewNode:XML=<itemlabel='Child4'isBranch="true"></item>;
  38. xmlBound2Tree.dataDescriptor.addChildAt(dataX,newNode,2,dataX);
  39. }
  40. ]]>
  41. </mx:Script>
  42. <mx:Labeltext="TreewithXMLdata"/>
  43. <mx:Treeid="xmlBound2Tree"dataProvider="{dataX}"labelField="@label"showRoot="true"width="200"/>
  44. <mx:Buttonlabel="AddEmptyBranchthroughthedataProvider"click="addEmptyBranchDP();"/>
  45. <mx:Buttonlabel="AddEmptyBranchthroughthedataDescriptor"click="addEmptyBranchDD();"/>
  46. <mx:Spacerheight="10"/>
  47. <mx:Labeltext="Treewithobjectdata"/>
  48. <mx:Treeid="objGraphBound2Tree"dataProvider="{dataObj}"width="200"/>
  49. <mx:Buttonlabel="AddEmptyBranchthroughthedataProvider"click="addEmptyBranchDP2();"/>
  50. </mx:Application>

结果


打开树到指定的节点

默认的,Tree控件在初始化后是收缩的,你也许不确定如何初始化控件时展开数,并且选定指定的节点。下边的例子,展示了如何实现它。在这个程序中,initTree()方法,在Tree控件被创建后调用。这个方法展开Tree控件的根节点,并且设置selectedIndex属性为指定节点的索引号。

  1. <?xmlversion="1.0"?>
  2. <mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"viewSourceURL="src/index.html"><mx:Script>
  3. <![CDATA[
  4. importFlash.events.*;
  5. importmx.events.*;
  6. importmx.controls.*;
  7. privatefunctioninitTree():void{
  8. XMLTree1.expandItem(MailBox.getItemAt(0),true);
  9. XMLTree1.selectedIndex=2;
  10. }
  11. ]]>
  12. </mx:Script>
  13. <mx:Treeid="XMLTree1"width="150"height="170"
  14. labelField="@label"creationComplete="initTree();">
  15. <mx:XMLListCollectionid="MailBox">
  16. <mx:XMLList>
  17. <nodelabel="Mail"data="100">
  18. <nodelabel="Inbox"data="70"/>
  19. <nodelabel="PersonalFolder"data="10">
  20. <nodelabel="Business"data="2"/>
  21. <nodelabel="Demo"data="3"/>
  22. <nodelabel="SavedMail"data="5"/>
  23. </node>
  24. <nodelabel="Sent"data="15"/>
  25. <nodelabel="Trash"data="5"/>
  26. </node>
  27. </mx:XMLList>
  28. </mx:XMLListCollection>
  29. </mx:Tree>
  30. </mx:Application>

结果


读取多节点名XML文档


你可以从具有多个节点名字的XML文档中组装Tree 控件。下边的例子实现了这个功能。Tree控件的数据提供者是一个XMLListCollection,它组装自一个包含folder和Pfolder元素的XMLList。Tree控件的labelField属性被设置为label属性,不管元素叫什么名字,这个属性对XMLList中的所有属性都是公共的。

例子

  1. <?xmlversion="1.0"?>
  2. <mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"viewSourceURL="src/index.html">
  3. <mx:Treeid="tree1"dataProvider="{MailBox}"labelField="@label"showRoot="true"width="160"/>
  4. <mx:XMLListCollectionid="MailBox"source="{Folders}"/>
  5. <mx:XMLListid="Folders">
  6. <folderlabel="Mail">
  7. <folderlabel="INBOX"/>
  8. <folderlabel="PersonalFolder">
  9. <Pfolderlabel="Business"/>
  10. <Pfolderlabel="Demo"/>
  11. <Pfolderlabel="SavedMail"/>
  12. </folder>
  13. <folderlabel="Sent"/>
  14. <folderlabel="Trash"/>
  15. </folder>
  16. </mx:XMLList>
  17. </mx:Application>
结果


当数据提供器更新时保持Tree控件打开


默认地,当数据提供器更新数据时Tree控件收缩。下边的例子展示了当数据提供器更新时保持Tree控件打开的方法。
在这个应用程序中,当一个用户单击Button控件时changeProvider()方法更新数据提供器。通常,这会导致Tree控件收缩。然而,Tree控件的渲染事件处理器,renderTree()方法,放置收缩的发生。当changerProvider()方法被调用,当前状态是打开的元素被保存到对象open变量中。当数据被刷新时,被命名为refreshData的Boolean类型的变量被置为true。renderTree()方法调用Tree控件的invalidateList()方法来刷新树的行。然后置refreshDate属性为false,并且重置Tree控件的打开元素属性为open对象变量,这个变量在刷新前就包含了状态是打开的元素。


例子

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"layout="vertical"initialize="initTree()"viewSourceURL="srcview/index.html">
  3. <mx:Script>
  4. <![CDATA[
  5. [Bindable]
  6. publicvaropen:Object=newObject();
  7. [Bindable]
  8. publicvarrefreshData:Boolean=false;
  9. [Bindable]
  10. publicvarswitchObj:Object=newObject();
  11. [Bindable]
  12. publicvarfirstObj:Object=newObject();
  13. [Bindable]
  14. publicvarfirstObj1:Object=newObject();
  15. [Bindable]
  16. publicvarfirstObj2:Object=newObject();
  17. [Bindable]
  18. publicvarprovider:String="firstObj";
  19. privatefunctioninitTree():void
  20. {
  21. firstObj=newObject();
  22. firstObj.label="Foods";
  23. firstObj.children=newArray();
  24. firstObj1.label="Fruits";
  25. firstObj1.children=newArray();
  26. firstObj2.label="Oranges";
  27. firstObj1.children[0]=firstObj2;
  28. firstObj.children[0]=firstObj1;
  29. switchObj=firstObj;
  30. }
  31. publicfunctionchangeProvider():void
  32. {
  33. open=SampleTree.openItems;
  34. refreshData=true;
  35. if(provider=="firstObj")
  36. {
  37. provider="switchObj";
  38. SampleTree.dataProvider=switchObj;
  39. }
  40. else
  41. {
  42. provider="firstObj";
  43. SampleTree.dataProvider=firstObj;
  44. }
  45. }
  46. publicfunctionrenderTree():void{
  47. if(refreshData){
  48. //Refreshallrowsonnextupdate.
  49. SampleTree.invalidateList();
  50. refreshData=false;
  51. SampleTree.openItems=open;
  52. //Validateandupdatethepropertiesandlayout
  53. //ofthisobjectandredrawit,ifnecessary.
  54. SampleTree.validateNow();
  55. }
  56. }
  57. ]]>
  58. </mx:Script>
  59. <mx:Treeid="SampleTree"render="renderTree()"width="250"dataProvider="{firstObj}"labelField="label"/>
  60. <mx:Buttonlabel="ChangeDataProvider"click="changeProvider()"/>
  61. </mx:Application>
结果

项和一个树控件拖放

拖拽元素到Tree控件,和从Tree控件拖拽出元素创建一个应用程序,实现拖拽元素从Tree控件中,或到Tree控件是令人畏惧的,很明显,因为需要大量的事件处理逻辑。本节提供2个例子,来示范实现这2种功能的技术。从Tree控件中拖拽出元素下边的例子展示如何从Tree控件中拖拽元素到DataGrid控件中。Tree控件的数据提供器是XML对象。通过拖拽事件处理方法前的注释可以使你读懂整个应用程序。

例子

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"layout="absolute">
  3. <mx:Script>
  4. <![CDATA[
  5. importmx.controls.Alert;
  6. importmx.controls.Label;
  7. importmx.controls.List;
  8. importmx.collections.ArrayCollection;
  9. importmx.core.DragSource;
  10. importmx.controls.Tree;
  11. importmx.controls.DataGrid;
  12. importmx.controls.listClasses.ListBase;
  13. importmx.events.DragEvent;
  14. importmx.containers.Canvas;
  15. importmx.managers.DragManager;
  16. importmx.core.UIComponent;
  17. [Bindable]
  18. privatevardataGridProvider:ArrayCollection=newArrayCollection();
  19. /**
  20. *HandlesthedragEntereventontheDataGridcontrol.
  21. *IfthedragInitiatoristheTreecontrol,thenonlynodesoftype"restaurant"
  22. *arepermittedtobedropped.
  23. *HereyoucanseethatbyexaminingthedragSourceyoucandetermineif
  24. *thecontrolshouldacceptthedrop.TheDataGridcontrolwouldnot
  25. *knowhowtotreatabranch+childrenfromtheTreecontrol,soonlyleaf(restaurant)
  26. *nodesareaccepted.
  27. */
  28. privatefunctiononDragEnter(event:DragEvent):void
  29. {
  30. if(event.dragInitiatorisTree){
  31. vards:DragSource=event.dragSource;
  32. if(!ds.hasFormat("treeItems"))return;//nousefuldata
  33. varitems:Array=ds.dataForFormat("treeItems")asArray;
  34. for(vari:Number=0;i<items.length;i++){
  35. varitem:XML=XML(items[i]);
  36. if(item.@type!="restaurant")return;//notwhatwewant
  37. }
  38. }
  39. //IftheTreecontrolpassesorthedragInitiatorisnotaTreecontrol,
  40. //acceptthedrop.
  41. DragManager.acceptDragDrop(UIComponent(event.currentTarget));
  42. }
  43. /**
  44. *HandlesthedragOvereventontheDataGridcontrol.
  45. *IfthedragInitiatoristheTreecontrol,onlycopyisallowed.Otherwise,amove
  46. *orlinkcantakeplacefromtheListcontrol.
  47. */
  48. privatefunctiononDragOver(event:DragEvent):void
  49. {
  50. if(event.dragInitiatorisTree){
  51. DragManager.showFeedback(DragManager.COPY);
  52. }else{
  53. if(event.ctrlKey)
  54. DragManager.showFeedback(DragManager.COPY);
  55. elseif(event.shiftKey)
  56. DragManager.showFeedback(DragManager.LINK);
  57. else{
  58. DragManager.showFeedback(DragManager.MOVE);
  59. }
  60. }
  61. }
  62. /**
  63. *HandlesthedragExiteventonthedroptargetandjusthidesthe
  64. *thedropfeedback.
  65. */
  66. privatefunctiononDragExit(event:DragEvent):void
  67. {
  68. vardropTarget:ListBase=ListBase(event.currentTarget);
  69. dropTarget.hideDropFeedback(event);
  70. }
  71. /**
  72. *HandlesthedragDropeventontheDataGridwhenthe
  73. *dragproxyisreleased.
  74. */
  75. privatefunctiononGridDragDrop(event:DragEvent):void
  76. {
  77. vards:DragSource=event.dragSource;
  78. vardropTarget:DataGrid=DataGrid(event.currentTarget);
  79. vararr:Array;
  80. if(ds.hasFormat("items")){
  81. arr=ds.dataForFormat("items")asArray;
  82. }elseif(ds.hasFormat("treeItems")){
  83. arr=ds.dataForFormat("treeItems")asArray;
  84. }
  85. for(vari:Number=0;i<arr.length;i++){
  86. varnode:XML=XML(arr[i]);
  87. varitem:Object=newObject();
  88. item.label=node.@label;
  89. item.type=node.@type;
  90. dataGridProvider.addItem(item);
  91. }
  92. onDragExit(event);
  93. }
  94. /**
  95. *InterceptsthedragCompleteeventontheTreecontrol
  96. *andpreventsthedefaultbehaviorfromhappening.Thisisnecessary
  97. *iftheitembeingdraggedfromtheTreecontrolisdroppedonanon-Tree
  98. *object,suchastheDataGrid.
  99. */
  100. privatefunctiononTreeDragComplete(event:DragEvent):void{
  101. event.preventDefault();
  102. }
  103. /**
  104. *SelectsalloftheitemsintheListifCtrl+AispickedwhentheListcontrol
  105. *hasfocus.
  106. */
  107. privatefunctionselectAllMaybe(event:KeyboardEvent):void
  108. {
  109. if(event.ctrlKey&&event.keyCode==65){
  110. varl:List=List(event.currentTarget);
  111. varallItems:Array=newArray(l.dataProvider.length);
  112. for(vari:Number=0;i<allItems.length;i++){
  113. allItems[i]=i;
  114. }
  115. l.selectedIndices=allItems;
  116. }
  117. }
  118. ]]>
  119. </mx:Script>
  120. <mx:XMLid="treeData"xmlns="">
  121. <root>
  122. <nodelabel="Massachusetts"type="state"data="MA">
  123. <nodelabel="Boston"type="city">
  124. <nodelabel="SmokeHouseGrill"type="restaurant"/>
  125. <nodelabel="Equator"type="restaurant"/>
  126. <nodelabel="Aquataine"type="restaurant"/>
  127. <nodelabel="Grill23"type="restaurant"/>
  128. </node>
  129. <nodelabel="Provincetown"type="city">
  130. <nodelabel="LobsterPot"type="restaurant"/>
  131. <nodelabel="TheMews"type="restaurant"/>
  132. </node>
  133. </node>
  134. <nodelabel="California"type="state"data="CA">
  135. <nodelabel="SanFrancisco"type="city">
  136. <nodelabel="FrogLane"type="restaurant"/>
  137. </node>
  138. </node>
  139. </root>
  140. </mx:XML>
  141. <mx:Labelx="34"y="40"text="DragitemsfromthisTree"/>
  142. <mx:Labelx="34"y="55"text="(itemsarecopied)"/>
  143. <mx:Treex="34"y="81"width="181"height="189"
  144. dataProvider="{treeData.node}"
  145. labelField="@label"
  146. dropEnabled="false"
  147. dragEnabled="true"
  148. dragComplete="onTreeDragComplete(event)"
  149. dragMoveEnabled="false"
  150. />
  151. <mx:Labelx="291"y="55"text="DropitemsfromTreehere"/>
  152. <mx:DataGridx="291"y="81"height="189"
  153. dragEnabled="true"
  154. dataProvider="{dataGridProvider}"
  155. dragEnter="onDragEnter(event)"
  156. dragOver="onDragOver(event)"
  157. dragDrop="onGridDragDrop(event)"
  158. dragExit="onDragExit(event)">
  159. <mx:columns>
  160. <mx:DataGridColumnheaderText="Label"dataField="label"/>
  161. <mx:DataGridColumnheaderText="Type"dataField="type"/>
  162. </mx:columns>
  163. </mx:DataGrid>
  164. </mx:Application>

树控件拖放

下面的示例演示如何将项从列表控件拖到树控件。 树数据提供程序是XML对象。

例子

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"layout="absolute">
  3. <mx:Script>
  4. <![CDATA[
  5. importmx.events.DragEvent;
  6. importmx.managers.DragManager;
  7. importmx.core.DragSource;
  8. importmx.core.UIComponent;
  9. importmx.controls.Tree;
  10. /**
  11. *CalledassoonasthedragProxyentersthetarget.Youcanaddlogic
  12. *todetermineifthetargetwillacceptthedropbasedonthe
  13. *dragInitiator,thedataavailableinthedragSource.
  14. *Herethedropisblindlyaccepted.
  15. */
  16. privatefunctiononDragEnter(event:DragEvent):void
  17. {
  18. DragManager.acceptDragDrop(UIComponent(event.currentTarget));
  19. }
  20. /**
  21. *CalledwhilethedragProxyisoverthedroptarget.Youcan
  22. *usethisfunctiontodeterminethetypeoffeedbacktoshow.
  23. *SincetheListissettoallowMOVE(theitemisdeleted
  24. *oncedropped),differentfeedbackpossibilitiesaregiven.
  25. *
  26. *Also,forthisapplication,theTreecontrolnodethedragProxyis
  27. *overisselected.AsthedragProxymoves,theTreecontrol's
  28. *selectionchanges.
  29. *
  30. *Forabitmorecomplication,thedropisbeingallowed
  31. *onlyovernodeswhosetypeisNOT'state'.
  32. *Thefeedbackisremoved.
  33. */
  34. privatefunctiononDragOver(event:DragEvent):void
  35. {
  36. vardropTarget:Tree=Tree(event.currentTarget);
  37. varr:int=dropTarget.calculateDropIndex(event);
  38. tree.selectedIndex=r;
  39. varnode:XML=tree.selectedItemasXML;
  40. if(node.@type=="state"){
  41. DragManager.showFeedback(DragManager.NONE);
  42. return;
  43. }
  44. if(event.ctrlKey)
  45. DragManager.showFeedback(DragManager.COPY);
  46. elseif(event.shiftKey)
  47. DragManager.showFeedback(DragManager.LINK);
  48. else{
  49. DragManager.showFeedback(DragManager.MOVE);
  50. }
  51. }
  52. /**
  53. *CalledwhenthedragProxyisreleased
  54. *overthedroptarget.TheinformationinthedragSource
  55. *isextractedandprocessed.
  56. *
  57. *Thetargetnodeisdeterminedand
  58. *allofthedataselected(theListhasallowMultipleSection
  59. *set)isadded.
  60. */
  61. privatefunctiononDragDrop(event:DragEvent):void
  62. {
  63. vards:DragSource=event.dragSource;
  64. vardropTarget:Tree=Tree(event.currentTarget);
  65. varitems:Array=ds.dataForFormat("items")asArray;
  66. varr:int=tree.calculateDropIndex(event);
  67. tree.selectedIndex=r;
  68. varnode:XML=tree.selectedItemasXML;
  69. varp:*;
  70. //iftheselectednodehaschildren(itistype==city),
  71. //thenaddtheitemsatthebeginning
  72. if(tree.dataDescriptor.hasChildren(node)){
  73. p=node;
  74. r=0;
  75. }else{
  76. p=node.parent();
  77. }
  78. for(vari:Number=0;i<items.length;i++){
  79. varinsert:XML=<node/>;
  80. insert.@label=items[i];
  81. insert.@type="restaurant";
  82. tree.dataDescriptor.addChildAt(p,insert,r+i);
  83. }
  84. }
  85. /**
  86. *Calledwhenthedragoperationcompletes,whether
  87. *successfullyornot.Thetreeisclearedofits
  88. *selection.
  89. */
  90. privatefunctiononDragComplete(event:DragEvent):void
  91. {
  92. tree.selectedIndex=-1;
  93. }
  94. ]]>
  95. </mx:Script>
  96. <mx:XMLid="treeData"xmlns="">
  97. <root>
  98. <nodelabel="Massachusetts"type="state"data="MA">
  99. <nodelabel="Boston"type="city">
  100. <nodelabel="SmokeHouseGrill"type="restaurant"/>
  101. <nodelabel="Equator"type="restaurant"/>
  102. <nodelabel="Aquataine"type="restaurant"/>
  103. <nodelabel="Grill23"type="restaurant"/>
  104. </node>
  105. <nodelabel="Provincetown"type="city">
  106. <nodelabel="LobsterPot"type="restaurant"/>
  107. <nodelabel="TheMews"type="restaurant"/>
  108. </node>
  109. </node>
  110. <nodelabel="California"type="state"data="CA">
  111. <nodelabel="SanFrancisco"type="city">
  112. <nodelabel="FrogLane"type="restaurant"/>
  113. </node>
  114. </node>
  115. </root>
  116. </mx:XML>
  117. <mx:Arrayid="listData">
  118. <mx:String>JohnnyRocket's</mx:String>
  119. <mx:String>JetPizza</mx:String>
  120. <mx:String>Steve'sGreek</mx:String>
  121. <mx:String>Sonsie</mx:String>
  122. <mx:String>TheBorderCafe</mx:String>
  123. </mx:Array>
  124. <mx:Panelx="48"y="125"width="447"height="351"layout="absolute"title="DragontoTree">
  125. <mx:Treewidth="186"left="10"top="10"bottom="10"id="tree"
  126. labelField="@label"
  127. dataProvider="{treeData.node}"
  128. dropEnabled="false"
  129. dragMoveEnabled="false"
  130. dragEnter="onDragEnter(event)"
  131. dragOver="onDragOver(event)"
  132. dragDrop="onDragDrop(event)">
  133. </mx:Tree>
  134. <mx:Listwidth="188"height="206"right="10"bottom="10"id="list"
  135. allowMultipleSelection="true"
  136. dataProvider="{listData}"
  137. dragEnabled="true"
  138. dragMoveEnabled="true"
  139. dragComplete="onDragComplete(event)">
  140. </mx:List>
  141. <mx:Textx="229"y="10"text="Dragfromthelistbelowtothetree"width="188"height="39"/>
  142. <mx:Labelx="229"y="69"text="restaurants"/>
  143. </mx:Panel>
  144. </mx:Application>
结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值