FlexでTreeからListへDrag&Dropするサンプル

2011.08.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

FlexでTreeからListへのドラッグ&ドロップするサンプルを作ってみました。 TreeコンポーネントはListを継承しているのでプロパティだけでできるかと思ったのですがちょっと面倒でした。 サンプルでは左のTreeのお客様を右のリストに移動できるようにしています。

[SWF]http://public-blog-dev.s3.amazonaws.com/wp-content/uploads/2011/08/SampleDragDrop.swf,600,300[/SWF]

このサンプルを見るにはFlash Playerがインストールされている必要があります。

FLex SDKは4.5.1を使っています。 以下がソースになります。

<?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"
			   xmlns:local="*"
			   width="600" height="300">
	
	<fx:Declarations>
		<local:Company id="headOffice" name="本店">
			<local:companyList>
				<local:Company name="支店1">
					<local:customerList>
						<local:Customer name="お客様A"/>
						<local:Customer name="お客様B"/>
						<local:Customer name="お客様C"/>
					</local:customerList>
				</local:Company>
				<local:Company name="支店2">
					<local:customerList>
						<local:Customer name="お客様D"/>
						<local:Customer name="お客様E"/>
					</local:customerList>
				</local:Company>
			</local:companyList>
			
			<local:customerList>
			</local:customerList>
		</local:Company>
	</fx:Declarations>
	
	<fx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			import mx.events.DragEvent;
			import mx.managers.DragManager;
			
			[Bindable]
			private var selectedCustomer:ArrayCollection = new ArrayCollection();
			
			private function dragEnterHandler(event:DragEvent):void {
				var data:Object = new Array(event.dragSource.dataForFormat("treeItems"));
				var children:Array = data[0];
				
				for each(var child:Object in children) {
					if(child is Company) {
						return;
					}
				}
				
				event.preventDefault();
				
				var Initiator:* = event.target;
				DragManager.acceptDragDrop(Initiator);
			}
			
			private function dragOverHandler(event:DragEvent):void {
				event.preventDefault();
			}
			
			private function dragDropHandler(event:DragEvent):void {
				var data:Object = new Array(event.dragSource.dataForFormat("treeItems"));
				var children:Array = data[0];
				
				for each(var child:Object in children) {
					if(child is Customer) {
						selectedCustomer.addItem(child);
					}
				}
			}
		]]>
	</fx:Script>
	
	<s:HGroup width="100%" height="100%"
			  paddingTop="10"
			  paddingBottom="10"
			  paddingLeft="10"
			  paddingRight="10">
		<mx:Tree id="tree" 
				 width="100%"
				 height="100%"
				 labelField="name"
				 dragEnabled="true"
				 dragMoveEnabled="false"
				 dataProvider="{headOffice}"/>
		
		<s:VGroup width="100%" height="100%">
			<s:Label text="お客様リスト"/>
			<s:List id="childList" width="100%" height="100%"
					labelField="name"
					dragEnabled="true"
					dropEnabled="true"
					dragMoveEnabled="true"
					dragEnter="dragEnterHandler(event)"
					dragOver="dragOverHandler(event)"
					dragDrop="dragDropHandler(event)"
					dataProvider="{selectedCustomer}"/>
		</s:VGroup>
	</s:HGroup>
</s:Application>

エンティティクラスのソースになります。 ■Companyクラス

package {
	
public class Company {
	
	/** 店名 */
	public var name:String;
	
	/** 配下の支店リスト */
	public var companyList:Array = [];
	
	/** お客様リスト */
	public var customerList:Array = [];
	
	/** 子要素を取得する */
	public function get children():Array {
		if(companyList.length != 0) {
			return companyList;
		} else {
			return customerList;
		}
	}
}
}

■Customerクラス

package{
	
public class Customer {
	/** お客様名 */
	public var name:String;
}
}