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.

Reply via email to