Apache Adobe Flex TutorialTutoriaux Adobe Flex & AIR en Français

6fév/091

Flex Drag And Drop – Les évènements utilisables pour le Drag And Drop

Quand vous utilisez les capacités de Drag And Drop des composants Flex, le framework utilise plusieurs  évènements sans que vous le sachiez. Comprendre ces évènements vous permettra de modifier le comportement par défaut ou de coder complètement un drag and drop personnalisé.

Voici la liste des évènements, leurs cibles et ce qu'ils signifient:

  • mouseDown (Drag Initiator): C'est habituellement l'évènement qui déclenche le début d'une opération de drag and drop.
  • mouseMove (Drag Initiator): Dans certains cas, une opération de Drag And Drop ne peut se faire sans event mouseMove
  • dragEnter (Drop target): La souris est entrée dans la zone où il est possible de dépose, toujours en déplacant l'objet
  • dragMove (Drop target): La souris se déplace à l'intérieur de la zone cible. C'est un évènement similaire ou mouseMove sauf qu'il spécifie le composant cible (drop target)
  • dragExit (Drop target): La souris a été déplacée en dehors de la zone de drop,  toujours en déplacant l'objet
  • dragDrop (Drop target): L'utilisateur a lâché un objet sur la cible
  • dragComplete (Drag Initiator): Cet évènement se produit à chaque fois que l'utilisateur lâche l'objet, qu'il soit sur une drop zone ou pas.

Les évènements mouseDown et mouseMove sont des évènements standard de Flash Player, de type flash.event.MouseEvent. Le reste des évènements fait partie du framework Flex, et ils sont de type mx.events.DragEvent. Les objets DragEvent ont une propriété dragInitiator que donne une référence vers le composant d'où le drag and drop est parti. Ils ont aussi une propriété dragSource, de type mx.core.DragSource, qui contient la data copiée depuis le dragInitiator.

Les objets DragSource ont une méthode dataForFormat() qui requiert un paramètre (String) et retourne la donnée qui était stockée pour le format spécifié. Il y aura un tutorial à ce sujet. Pour le moment, vous devez savoir que les drag initiator de type liste créent toujours des objets DragSource avec un format appelé "items", et la donnée retournée par ce format est un Array de tous les éléments du data provider correspondant à la sélection de l'utilisateur. Par exemple, si l'utilisateur déplace un seul élément d'une DataGrid, l'objet DragSource contiendra un Array avec juste un élément.

Les objets DragSource ont aussi une propriété "action" qui indique une valeur  copy, move ou none. Pour faire des tests de comparaison, vous pouvez utiliser les constantes COPY, MOVE et NONE de la classe mx.managers.DragManager. La propriété "action" vous indique quelle action est attendue par l'opération de drag and drop. Cette valeur est fixée automatiquement quand on utilise le comportement drag and drop par défaut des composants.

Dans ce tutorial sur le déplacement d'éléments avec la propriété dragMoveEnabled,  on a vu qu'il était impossible en MXML de s'assurer que l'utilisateur fait bien un MOVE et pas un COPY. En utilisant les évènements et de l'ActionScript, on peut mettre ces sécurités en place comme dans cet exemple:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" horizontalAlign="center" viewSourceURL="srcview/index.html">
	<mx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			import mx.controls.DataGrid;
			import mx.managers.DragManager;
			import mx.events.DragEvent;

			private function dragCompleteHandler(event:DragEvent):void{
				if (event.action != DragManager.NONE){
					// l'utilisateur a tenté de faire un move ou un copy
					// on prend la référence vers la dataGrid dont est issue l'élement de drag and drop
					var grid:DataGrid = DataGrid(event.dragInitiator);
					// on prend une référence vers les données de cette grille
					var data:ArrayCollection = ArrayCollection(grid.dataProvider);
					// par défaut, le format est "items", avec cette ligne,
					// on prend une réf vers l'élément qui est déplacé
					var item:Object = event.dragSource.dataForFormat("items")[0];
					// on supprimer l'élément correspondant dans la DataGrid de départ
					for (var i:uint = 0; i < data.length ; i++){
						if (data.getItemAt(i).emailId == item.emailId){
							// suppression de l'élément
							data.removeItemAt(i);
							break;
						}
					}
				}
			}
		]]>
	</mx:Script>
	<mx:HBox width="100%" horizontalAlign="center">
		<mx:VBox height="100%">
			<mx:Label text="Boite de récéption" color="white" fontWeight="bold"/>
			<mx:DataGrid dragEnabled="true" dropEnabled="true" dragComplete="dragCompleteHandler(event)">
				<mx:columns>
					<mx:DataGridColumn headerText="Expediteur" dataField="from"/>
					<mx:DataGridColumn headerText="Destinataire" dataField="to"/>
					<mx:DataGridColumn headerText="Sujet" dataField="subject"/>
					<mx:DataGridColumn headerText="Date" dataField="date"/>
				</mx:columns>
				<mx:dataProvider>
					<mx:ArrayCollection>
						<mx:Object emailId="0" from="a@a.com" to="bob@fai.com"
							subject="Email important" date="05/02/2009"/>
						<mx:Object emailId="1" from="b@b.com" to="bob@fai.com"
							subject="Second Email important" date="05/02/2009"/>
						<mx:Object emailId="2" from="c@c.com" to="bob@fai.com"
							subject="Relance" date="05/02/2009"/>
						<mx:Object emailId="3" from="d@d.com" to="bob@fai.com"
							subject="Encore un" date="05/02/2009"/>							

					</mx:ArrayCollection>
				</mx:dataProvider>
			</mx:DataGrid>
		</mx:VBox>
		<mx:VBox height="100%">
			<mx:Label text="Corbeille" color="white" fontWeight="bold"/>
			<mx:DataGrid dragEnabled="true" dropEnabled="true" dragComplete="dragCompleteHandler(event)">
				<mx:columns>
					<mx:DataGridColumn headerText="Expediteur" dataField="from"/>
					<mx:DataGridColumn headerText="Destinataire" dataField="to"/>
					<mx:DataGridColumn headerText="Sujet" dataField="subject"/>
					<mx:DataGridColumn headerText="Date" dataField="date"/>
				</mx:columns>
			</mx:DataGrid>
		</mx:VBox>
	</mx:HBox>
</mx:Application>

Flex Source Code Download: Télécharger le code source complet de l'application

This movie requires Flash Player 11

Articles similaires

Commentaires (1) Trackbacks (1)
  1. Je trouve ça super compliqué l'utilisation du dragSource.dataForFormat('items')[0]...

    je viens de galéré une heure la dessus. Merci pour l'explication du dataForFormat() !

    ++


Leave a comment

(required)