The Skinny
By using mx:Tree dropEnabled=”false” and registering the drag and drop listeners separately using the addEventListener Method with the use_capture parameter set to true, items could be consistently dropped from one control into the tree control. Otherwise, the drop was broken, not working many times, and the red ‘x’ disallowed drop feedback would persist, even when the drop should have worked.
I got it to work by changing
albumTree.addEventListener(DragEvent.DRAG_ENTER, onDragEnter, false, 0, true);
TO
albumTree.addEventListener(DragEvent.DRAG_ENTER, onDragEnter, true, 0, true);
Be sure and add DragManager.acceptDragDrop(UIComponent(event.currentTarget)); to the onDragEnter method (See links and discussion below).
Working with drag and drop in Flex Tree Controls
First – make sure you are following the adobe documentation, and the great advice found in the following article:
http://weblogs.macromedia.com/pent/archives/2006/11/tree_drag_and_d.html
On the adobe site, there is a great article about how to drop on to a tree control(Key here is dropEnabled has to be false on the tree, and you do your own drag and drop handling). This seemed to work better than the simpler example above where dropEnabled was true. I think relying on the default behaviors (dropEnabled=”true”) is kind of iffy, unless you are doing really simple stuff. Check the section ‘Dragging and Dropping to a tree control’ near the bottom:
http://www.adobe.com/devnet/flex/quickstart/working_with_tree/
The dropEnabled property of the tree component handles drag and drop in certain ways in which it makes it hard to override or use your own drag and drop event listening at the same time.
Also, if you have nested components and/or a more complex mxml interface, you may run into the following problem –
A flex tree nested in a few components was not accepting drops from a tileList nested in a few components. I think in traversing the components that the drag_enter precedence or firing was getting screwed up and not allowing drops. It would only accept drops sometimes. As you dragged over a VBox divider, the drop indicator (feedback) was showing a red x, and often, but not always, the red x would persist into the drop target the SHOULD have been allowing drops and drag enter. It was turning out that a slow drag would allow a drop, but a fast drag over to the drop target was not allowed, where the red x persisted.
Adding DragManager.acceptDragDrop(UIComponent(this)); where this is the parent container, just makes everything in the parent container accept a drop, which is not what I was looking to do. And it’s kludgey.
I got it to work changing albumTree.addEventListener(DragEvent.DRAG_ENTER, onDragEnter, false, 0, true); TO albumTree.addEventListener(DragEvent.DRAG_ENTER, onDragEnter, true, 0, true);
For some reason the use_capture parameter fixed this. The key (which I don’t posses yet) is in understanding the different phases of event processing. Capture, target, and bubble.
Adobe – “The use_capture parameter of the addEventListener()
method lets you control the phase in the event flow in which your listener will be active. It sets the value of the useCapture
property of the Event object. If useCapture
is set to true
, your listener is active during the capturing phase of the event flow. If useCapture
is set to false
, your listener is active during the targeting and bubbling phases of the event flow but not during the capturing phase. The default value is determined by the type of event, but is false
in most cases.
To listen for an event during all phases of the event flow, you must call addEventListener()
twice, once with the use_capture parameter set to true
, and again with use_capture set to false
. This argument is optional. For more information, see Capturing phase.”
Note – Changing the event priority higher didn’t work (albumTree.addEventListener(DragEvent.DRAG_ENTER, onDragExit, false, 10, true);)