Avg. Rating 3.5

Problem

The AdvancedDataGrid visually achieves both the folder structure of a Tree and the columns of a DataGrid, but takes a flat data set. In my case, I needed a component that would allow me to customize the data structure in an hierarchical fashion.

Solution

The TreeGrid component that is a part of the Flexlib component library achieves the visual effects of the AdvancedDataGrid, while accepting a hierarchical data set.

Detailed explanation

Below I built a dummy dataset with nested "FileDescriptors" by way of it's Children property. To inform the Tree of the data's structure, I created a HierarchyDataDescriptor object that extends DefaultDataDescriptor.

Visually, I supply icons for the different states of the folders and items (ex. disclosureClosedIcon, disclosureOpenIcon, etc...).

There are many more properties you can use to customize the TreeGrid so definitely check out the docu for flexlib.

NOTE: Before looking to third-party libraries, I recommend browsing the flex3 component explorer found here http://examples.adobe.com/flex3/componentexplorer/explorer.html.

TGrid.mxml:


<mx:Application 
	xmlns:mx="http://www.adobe.com/2006/mxml" 
	layout="absolute" 
	xmlns:code="http://code.google.com/p/flexlib/"
	initialize="handleInitialize(event)"
	>
	
	<mx:Script>
		<![CDATA[
			import model.descriptors.HierarchyDataDescriptor;
			import model.descriptors.FileDescriptor;
			import mx.events.FlexEvent;
			import mx.collections.ArrayCollection;
			
			private function handleInitialize(event:FlexEvent):void{
				var root:FileDescriptor = new FileDescriptor();
				root.Name = "Home";
				root.Size = "--";
				root.Type = "Folder";
				root.Children = new ArrayCollection();
				
				for (var i:int = 0; i<10; i++){
					var currentFile:FileDescriptor = new FileDescriptor();
					currentFile.Name = "Item "+i;
					currentFile.Size = (10*(i+1)) + " KB";
					currentFile.Type = "File";
					root.Children.addItem(currentFile);
				}
				
				list.dataDescriptor = new HierarchyDataDescriptor();
				list.dataProvider = root;
			}
			
		]]>
	</mx:Script>
	
	<code:TreeGrid
		id="list"
		width="80%" height="100%"
		disclosureClosedIcon="@Embed(source='/assets/icons/arrow_right.png')"
		disclosureOpenIcon="@Embed(source='/assets/icons/arrow_down.png')"
		folderOpenIcon="@Embed(source='/assets/icons/folder.png')"
		folderClosedIcon="@Embed(source='/assets/icons/folder.png')"
		defaultLeafIcon="@Embed(source='/assets/icons/page.png')"
		>
		<code:columns>
			<code:TreeGridColumn dataField="Name" />
			<mx:DataGridColumn dataField="Size" />
			<mx:DataGridColumn dataField="Type" />
		</code:columns>
	</code:TreeGrid>
	
</mx:Application>

FileDescriptor.as

package model.descriptors
{
	import mx.collections.ArrayCollection;
	
	public class FileDescriptor
	{
		public function FileDescriptor(){}

		public var Name:String;
		public var Size:String;
		public var Type:String;
		public var Children:ArrayCollection;

	}
}

HierarchyDataDescriptor.as

package model.descriptors
{
	import mx.collections.ArrayCollection;
	import mx.collections.ICollectionView;
	import mx.controls.treeClasses.DefaultDataDescriptor;

	public class HierarchyDataDescriptor extends DefaultDataDescriptor
	{
		public function HierarchyDataDescriptor()
		{
			super();
		}
		
		override public function getChildren(node:Object, model:Object=null):ICollectionView
		{
			return node.Children;
		}
		
		override public function hasChildren(node:Object, model:Object=null):Boolean
		{
			return node != null && node.Children != null && (node.Children as ArrayCollection) != null && (node.Children as ArrayCollection).length > 0;
		}
		
		override public function isBranch(node:Object, model:Object=null):Boolean
		{
			return hasChildren(node, model);
		}
		
		override public function getData(node:Object, model:Object=null):Object
		{
			return node;
		}
		
	}
}
TGrid.zip
[Project source including the Flexlib SWC file and icon files.]
Report abuse

Related recipes