Wow, what can I say Mr Caraion, you are a LEGEND. Thank you so much for taking the time to help me. I REALLY APPRECIATE IT!
I will be remoting to ColdFusion to get and set the data so I will investigate using an ArrayCollection instead of XML. I think I will need to use the Tree's dataDescriptor to work with the children of nodes but am still investigating this. Thanks again! Nathan --- In [email protected], "mrcaraion" <mrcara...@...> wrote: > > Hi > > Try this: > > // main.mxml > <?xml version="1.0" encoding="utf-8"?> > <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"> > > <mx:Script> > <![CDATA[ > import mx.events.ListEvent; > import com.nathan.descriptors.DocumentTreeDataDescriptor; > > [Bindable] > public var treeData:XML = <node type='folder' data='' label='Folder: > ABC'> > <node type='document' data='123' > label='ABC01'/> > <node type='document' data='124' > label='ABC02'> > <node type='page' data='125' > label='ABC03'/> > <node type='page' data='126' > label='ABC04'/> > <node type='page' data='127' > label='ABC05'/> > </node> > <node type='document' data='128' > label='ABC06'/> > <node type='document' data='129' > label='ABC07'/> > </node>; > > private function tree_itemDoubleClickHandler(event:ListEvent):void > { > var node:XML = XML(event.itemRenderer.data); > > // check whether a node of type page is double clicked > if (no...@type == "page") > { > var pageDocument:XML = node.parent(); // > Tree(event.target).getParentItem(node); > var documentFolder:XML = pageDocument.parent(); // > Tree(event.target).getParentItem(pageDocument); > var newDocumentNode:XML = <node type='document' data={no...@data} > label={no...@label} /> > > XML(documentFolder).insertChildAfter(pageDocument, newDocumentNode); > > var nodeIndex:int = node.childIndex(); > var documentPages:XMLList = pageDocument.children(); > > // store the length of documentPages in a variable, because > // the real length will decrease by one each time we remove > // a child from the document. In addition to this keep in mind > > // that after removing a child the subsequent child will take > // its place, thus we retrieve and remove nodes at the same index: > nodeIndex. > var length:int = documentPages.length(); > for (var i:uint = nodeIndex; i < length; i++) > { > var pageNode:XML = documentPages[nodeIndex]; > > delete documentPages[nodeIndex]; > > if (i != nodeIndex) > { > newDocumentNode.appendChild(pageNode); > } > } > > // if the document has no children, close it. > if (XML(pageDocument).children().length() == 0) > Tree(event.target).expandItem(pageDocument, false); > } > } > > ]]> > </mx:Script> > > <mx:Tree id="tree" dataProvider="{treeData}" labelField="@label" width="300" > doubleClickEnabled="true" dataDescriptor="{new > DocumentTreeDataDescriptor()}" > itemRenderer="com.nathan.itemRenderers.DocumentTreeItemRenderer" > itemDoubleClick="tree_itemDoubleClickHandler(event)"/> > > </mx:Application> > > You will have to extend two more classes, DefaultDataDescriptor and > TreeItemRenderer, to tell to Tree component, through overriden isBranch > method from the DocumentDataDescriptor, that if a node is of type 'document' > than this is a branch; in DocumentTreeItemRenderer you hide the > disclosureIcon if the node is a branch but has no children. This is done to > fix some visual, I think, incorrect behavior (like the document node looks > like a leaf node when it has no pages ...). > > // com/nathan/itemRenderers/DocumentTreeItemRenderer.as > > package com.nathan.itemRenderers > { > import mx.controls.Tree; > import mx.controls.treeClasses.TreeItemRenderer; > > public class DocumentTreeItemRenderer extends TreeItemRenderer > { > public function DocumentTreeItemRenderer() > { > super(); > } > > override protected function > updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void > { > super.updateDisplayList(unscaledWidth, unscaledHeight); > > if (listData && disclosureIcon) > { > var owner:Tree = listData.owner as Tree; > var node:Object = data; > > if (owner.dataDescriptor.isBranch(node) && > owner.dataDescriptor.hasChildren(node)) > disclosureIcon.visible = true; > else > disclosureIcon.visible = false; > } > } > > } > } > > // com/nathan/descriptors/DocumentTreeDataDescriptor.as > > package com.nathan.descriptors > { > import mx.collections.ICollectionView; > import mx.controls.treeClasses.DefaultDataDescriptor; > > public class DocumentTreeDataDescriptor extends DefaultDataDescriptor > { > public function DocumentTreeDataDescriptor() > { > } > > override public function isBranch(node:Object, > model:Object=null):Boolean > { > if (no...@type == "document") > return true; > > return super.isBranch(node, model); > } > > } > } > > You can also use an ArrayCollection for all this, the advantage is that you > may want to use strong typed objects for your data and to request this data > from a RemoteObject through AMF protocol, this will have a positive impact on > app performance. > > Best regards, > Mr caraion. >

