ActionScript 3, Flex, Tutorials

Flex 2 Drag’n’Drop Howto – Datagrid Drop Into

Inauguro con questo tutorial la finora linda categoria Flex 😀

Il breve tutorial che andrete a leggere verte su come fare un semplice drag n drop tra 2 list component in modo che gli item dell’uno fungano come target al drop degli elementi dell’altro (una possibile applicazione potrebbe essere quella di spostare dei files all’interno di una lista di cartelle).

Il drag n drop standard:

Flex permette di abilitare il drag n drop tra due component direttamente da mxml, senza tanti problemi, abilitando le proprietà dragEnabled e dropEnabled dei componenti desiderati.

Il risultato che si ottiene abilitando dragEnabled e dropEnabled è questo:

[flash http://www.flashfuck.it/wp-content/uploads/2007/11/dragdropintoko.swf w=400 h=300]

Droppando gli elementi della tilelist all’interno del datagrid questi verranno clonati ed aggiunti allo stesso datagrid. Le righe del datagrid non sono selezionabili, i nuovi elementi sono aggiunti prima o dopo i record già presenti.


Il drag n drop into:

Mi ci sono scervellato un pò, ho tirato in ballo varie community, ma alla fine la soluzione era nel langRef di flex (come al solito :))

Prendiamo in considerazione la struttura dell’applicazione

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:HBox width="100%" height="100%">
<mx:DataGrid width="50%" height="100%" id="drop_dg">
<mx:columns>
<mx:DataGridColumn headerText="Directories" dataField="label"/>
</mx:columns>
<mx:dataProvider>
<mx:ArrayCollection>
<mx:Array>
<mx:Object label='directory 1'/>
<mx:Object label='directory 2'/>
<mx:Object label='directory 3'/>
<mx:Object label='directory 4'/>
</mx:Array>
</mx:ArrayCollection>
</mx:dataProvider>
</mx:DataGrid>
<mx:TileList width="50%"
height="100%"
labelField="label"
dragEnabled="true"
id="drag_tl"
columnWidth="50"
rowHeight="50"
allowMultipleSelection="true">
<mx:dataProvider>
<mx:ArrayCollection>
<mx:Array>
<mx:Object label='item 1'/>
<mx:Object label='item 2'/>
<mx:Object label='item 3'/>
<mx:Object label='item 4'/>
</mx:Array>
</mx:ArrayCollection>
</mx:dataProvider>
</mx:TileList>
</mx:HBox>
</mx:Application>

E’ piuttosto semplice: una HBox contenente un datagrid (drop_dg) e una tilelist (drag_tl), entrambi con il loro dataprovider, e la tilelist ha abilitato il dragEnabled in modo che i suoi elementi possano essere draggati (il datagrid non ha dropEnabled=true).

A questo punto se testiamo l’applicazione il drag degli elementi non porterà a nulla in quanto non esistono drop designati.

Iniziamo a scriptare questa struttura, sarà necessario importare le classi
– mx.core.DragSource
– mx.events.ListEvent
– mx.events.DragEvent
– mx.managers.DragManager
per far funzionare il tutto…e anche mx.controls.Alert ai fini dell’esempio portato nel tutorial.

Adesso è necessario definire alcuni metodi

private var _tempIndex:uint=0;//indice della cartella selezionata

//gestore dragEnter del datagrid
private function onDragEnter(e:DragEvent):void
{
	DragManager.acceptDragDrop(drop_dg);
}
//gestore dragOver del datagrid -> gestisce il "rollover" sugli elementi sotto il drag proxy
private function onDragOver(e:DragEvent):void
{
	drop_dg.selectedIndex = drop_dg.calculateDropIndex(e);
	DragManager.showFeedback(DragManager.MOVE);
}
//gestore del dragDrop del datagrid -> clona gli elementi droppati e li copia nel datagrid
private function onDragDrop(e:DragEvent):void
{
	var ds:DragSource = e.dragSource;
	var items:Array = ds.dataForFormat('items') as Array;
	var txt:String ="";
	for(var i:uint=0;i0){txt+=", ";}
		txt+=items[i].label;
	}
	txt+=" dropped into "+drop_dg.selectedItem.label;
	Alert.show(txt,"Dropped!");
	drop_dg.selectedIndex = _tempIndex;
}
//riposiziona il focus del datagrid al precedente indice
private function onDragComplete(e:DragEvent):void
{
	drop_dg.selectedIndex = _tempIndex;
}
//memorizza il focus da mantenere nel datagrid
private function onDgItemClick(e:ListEvent):void
{
	_tempIndex = drop_dg.selectedIndex;
}

dopo aver definito questi metodi per la gestione del dragdrop sarà necessario aggiungerne i gestori al datagrid direttamente dall’mxml:


dragEnter="onDragEnter(event)"
dragOver="onDragOver(event)"
dragComplete="onDragComplete(event)"
dragDrop="onDragDrop(event)"
itemClick="onDgItemClick(event)"

…e ora testando l’applicazione il risultato sarà il seguente

[flash http://www.flashfuck.it/wp-content/uploads/2007/11/dragdropintook.swf w=400 h=300]

Trascinando gli elementi sul datagrid non si avrà pi√π come riferimento il datagrid ma gli elementi del datagrid, grazie al metodo “calculateDropIndex” della classe ListBase (di cui DataGrid è un discendente).

Qui potete scaricare i files del tutorial: flashfuckdragndropinto.zip

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s