Manually adding drag-and-drop support

To support drag-and-drop operations with non-list-based controls, or with containers, you must explicitly add support by using a series of special classes and events.

Subtopics

Classes used in drag-and-drop operations
Drag-and-drop events
The drag-and-drop operation
Example: Accessing the drag data
Example: Simple drag-and-drop operation

Classes used in drag-and-drop operations

If you don't use the built-in functionality within list classes, you must manually add support for drag-and-drop operations. You use the following classes to implement the drag-and-drop operation:

Class

Function

DragManager

Manages the drag-and-drop operations; for example, its doDrag() method starts the drag operation.

DragSource

Identifies and contains the data being dragged. It also provides additional drag management features, such as the ability to add a listener that is called when data is requested.

DragEvent

Represents drag-and-drop events, such as when the user drags over a drag target.

Drag-and-drop events

Flex applications use events to control drag-and-drop operations. A control that acts as a drag initiator can use the following events to manage the drag-and-drop operation:

Event

Description

mouseDown and
mouseMove

The mouseDown event is dispatched when the user selects a control with the mouse and holds down the mouse button. The mouseMove event is dispatched when the mouse moves.

For most controls, you initiate the drag-and-drop operation in response to one of these events. Controls, such as Tree and Grid, that have a dragEnabled property, provide built-in support for initiating the drag operation; for these controls you do not use the mouse events.

dragComplete

Dispatched when a drag operation completes, either when the drag data drops onto a drop target, or when the drag-and-drop operation ends without performing a drop operation.

You can use this event to perform any final cleanup of the drag-and-drop operation. For example, if a user drags a List control item from one list to another, you can use the listener for this event to delete the List control item from the source.

The drop target can use the following events:

Event

Description

dragEnter

Dispatched when a drag proxy moves over the target from outside the target.

A component must define an event listener for this event to be a drop target. In the listener, you can change the appearance of the drop target to provide visual feedback to the user that the component can accept the drag operation. For example, you can draw a border around the drop target, or give focus to the drop target.

dragOver

Dispatched while the user moves the mouse over the target, after the dragEnter event.

You can handle this event to perform additional logic before allowing the drop operation, such as dropping data to various locations within the drop target, reading keyboard input to determine if the drag-and-drop operation is a move or copy of the drag data, or providing different types of visual feedback based on the type of drag-and-drop operation.

dragDrop

Dispatched when the user releases the mouse over the target.

You can only use this event listener to add the drag data to the drop target.

dragExit

Dispatched when the user drags outside the drop target, but does not drop the data onto the target.

You can use this event to restore the drop target to its normal appearance if you modified its appearance in response to a dragEnter event or other event.

The drag-and-drop operation

The following steps define the drag-and-drop operation:

  1. A component becomes a drag-and-drop initiator in either of the following ways:

    Components with a dragEnabled property (These components include List, Tree, DataGrid, PrintDataGrid, Menu, HorizontalList, and TileList.) If the dragEnabled property is set to true, Flex automatically makes the component an initiator when the user clicks and moves the mouse on the component.

    Components without dragEnabled properties For all other components, the component must sense the user's attempt to start a drag operation and explicitly become an initiator. Typically, you use the mouseMove or mouseDown event to start the drag-and-drop operation.

    1. The component creates an instance of the mx.core.DragSource class that contains the data to be dragged, and specifies the formats for the data.
    2. The component calls the mx.managers.DragManager.doDrag() method, to initiate the drag-and-drop operation.
  2. While the mouse button is still pressed, the user moves the mouse around the application. Flex displays the drag proxy image in your application. The DragManager.defaultDragImageSkin property defines the default drag proxy image.

    NOTE

     

    Releasing the mouse button when the drag proxy is not over a target ends the drag-and-drop operation. Flex generates a DragComplete event on the drag initiator, and the DragManager.getFeedback() method returns DragManager.NONE.

  3. If the user moves the drag proxy over a Flex component, Flex dispatches a dragEnter event to the component. The component must define an event listener for the dragEnter event to be a drop target.

    The dragEnter event listener can examine the DragSource object to determine whether the data being dragged is in an accepted format. To accept the drop, the event listener calls the DragManager.acceptDragDrop() method.

  4. (Optional) The drag target can handle the dragOver event. For example, the target can use this event listener to set the focus on itself.
  5. If the user decides not to drop the data onto the drop target and moves the drag proxy outside of the drop target without releasing the mouse button, Flex dispatches a dragExit event. The drop target can handle this event; for example, to undo any actions made in the dragOver event listener.
  6. If the user releases the mouse while over the drop target, Flex dispatches a dragDrop event. The drop target's dragDrop event listener adds the drag data to the target.
  7. If the drop operation completes, Flex dispatches a dragComplete event. The drag initiator can handle this event; for example, to delete the data from a data provider.

Example: Accessing the drag data

The following example uses the dragDrop event listener to access the data dragged from one DataGrid control to another. This example modifes the example from Example: DataGrid control to display the artist's name in an Alert control after a successful drag and drop operation:

<?xml version="1.0"?>
<!-- dragdrop\simpleDGToDGAlert.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    width="700" height="250" 
    borderStyle="solid" 
    creationComplete="initApp();">

    <mx:Script>
        <![CDATA[        
            import mx.events.DragEvent; 
            import mx.controls.Alert;
            
            private function initApp():void {
              srcgrid.dataProvider =  [
                {Artist:'Carole King', Album:'Tapestry', Price:11.99},
                {Artist:'Paul Simon', Album:'Graceland', Price:10.99},
                {Artist:'Original Cast', Album:'Camelot', Price:12.99},
                {Artist:'The Beatles', Album:'The White Album', Price:11.99}
              ];
                
                destgrid.dataProvider =[];    
            }

            // Define the event listener.
            public function dragDropHandler(event:DragEvent):void {    
                // Access dragged data as an Array 
                // in case multiple items were selected.
                var dragObj:Array=
                    event.dragSource.dataForFormat("items") as Array; 

                // Get the Artist for all dragged albums.
                var artistList:String='';
                for (var i:Number = 0; i < dragObj.length; i++) { 
                    artistList+='Artist: ' + dragObj[i].Artist + '\n';
                }
                
                Alert.show(artistList);                
            }           
        ]]>
    </mx:Script>

    <mx:HBox>
        <mx:VBox>
            <mx:Label text="Available Albums"/>
            <mx:DataGrid id="srcgrid" 
                allowMultipleSelection="true" 
                dragEnabled="true" 
                dropEnabled="true" 
                dragMoveEnabled="true">                
                <mx:columns>
                    <mx:DataGridColumn dataField="Artist"  />
                    <mx:DataGridColumn dataField="Album" />
                    <mx:DataGridColumn dataField="Price" />
                </mx:columns>    
            </mx:DataGrid>
        </mx:VBox>

        <mx:VBox>
            <mx:Label text="Buy These Albums"/>
            <mx:DataGrid id="destgrid" 
                allowMultipleSelection="true" 
                dragEnabled="true" 
                dropEnabled="true" 
                dragMoveEnabled="true" 
                dragDrop="dragDropHandler(event);">                
                <mx:columns>
                    <mx:DataGridColumn dataField="Artist"  />
                    <mx:DataGridColumn dataField="Album" />
                    <mx:DataGridColumn dataField="Price" />
                </mx:columns>    
            </mx:DataGrid>
        </mx:VBox>
    </mx:HBox>
</mx:Application>

Example: Simple drag-and-drop operation

The following example lets users color a canvas by dropping either of two sample colors onto it. It shows the basic elements of a drag-and-drop operation. The following sections describe these elements in greater detail.

<?xml version="1.0"?>
<!-- dragdrop\DandDCanvas.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:Script>
    <![CDATA[
        import mx.core.DragSource;
        import mx.managers.DragManager;
        import mx.events.*;
        import mx.containers.Canvas;

        // Called when the user clicks the mouse on either colored canvas.
        // Initializes the drag.
        private function dragIt(event:MouseEvent, text:String, 
            format:String):void {
            
            // Get the drag initiator component from the event object.
            var dragInitiator:Canvas=Canvas(event.currentTarget);
            // Create a DragSource object.
            var ds:DragSource = new DragSource();
            // Add the data to the object.
            ds.addData(text, format);

            // Create a Canvas container to use as the drag proxy.
            // You must specify a size for the proxy image, 
            // or else it will not appear.
            var canvasProxy:Canvas = new Canvas();
            canvasProxy.width=30;
            canvasProxy.height=30;
            canvasProxy.setStyle('backgroundColor',
                dragInitiator.getStyle('backgroundColor'));

            // Call the DragManager doDrag() method to start the drag. 
            // For information on this method, see 
            // the "Initiating the drag" section.
            DragManager.doDrag(dragInitiator, ds, event, canvasProxy);
        }

        // Called if the user dragged a proxy onto the drop target canvas.
        private function doDragEnter(event:DragEvent):void {
            // Get the drop target component from the event object.
            var dropTarget:Canvas=Canvas(event.currentTarget);

            // Accept the drag only if the user is dragging data 
            // identified by the 'color' format value.
            if (event.dragSource.hasFormat('color')) {
                DragManager.acceptDragDrop(dropTarget);
            }
        }
                
        // Called if the target accepts the dragged object and the user 
        // releases the mouse button while over the canvas. 
        // Handles the dragDrop event for the List control.
        private function doDragDrop(event:DragEvent):void {
            // Get the data identified by the color format 
            // from the drag source.
            var data:Object = event.dragSource.dataForFormat('color');
            // Set the canvas color.
            myCanvas.setStyle("backgroundColor", data);
        }
    
    ]]>
    </mx:Script>

    <!-- A horizontal box with red and green canvases the user can drag -->
    <mx:HBox>
        <mx:Canvas 
            width="30" height="30" 
            backgroundColor="red" 
            borderStyle="solid" 
            mouseMove="dragIt(event, 'red', 'color');"/>
        <mx:Canvas 
            width="30" height="30" 
            backgroundColor="green" 
            borderStyle="solid" 
            mouseMove="dragIt(event, 'green', 'color');"/>
    </mx:HBox>

    <mx:Label text="Drag the item into this canvas"/>

    <!-- Handles dragEnter and dragDrop events to allow dropping -->
    <mx:Canvas id="myCanvas" 
        width="100" height="100" 
        backgroundColor="#FFFFFF" 
        borderStyle="solid" 
        dragEnter="doDragEnter(event);" 
        dragDrop="doDragDrop(event);"/>
</mx:Application>

Flex 2.01

Take a survey