While diving into the Flex 4 spark framework I ran into a problem using
mx.managers.DragManager.doDrag()
with
mx.managers.DragManager.acceptDragDrop():
If you just drag, accept on dragDrop and then drop without moving the mouse you’ll get this error:
TypeError: Error #1009:
at mx.managers.dragClasses::DragProxy/mouseUpHandler()
[E:\dev\4…\mx\managers\dragClasses\DragProxy.as:591]
This is, because DragProxy
didn’t receive a MouseEvent
yet. So what you can do is manually send one. See this little use case and test for yourself:
<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" applicationComplete="construct()" height="100%" width="100%"> <fx:Script> <![CDATA[ import mx.controls.Alert; import mx.core.DragSource; import mx.core.UIComponent; import mx.managers.DragManager; private function construct() : void { // Get notified whan a global error occurs loaderInfo.uncaughtErrorEvents.addEventListener( UncaughtErrorEvent.UNCAUGHT_ERROR, errorHandler ); } private function onButtonMouseDown( event : MouseEvent ) : void { var button : UIComponent = UIComponent( event.target ); var dragSource:DragSource = new DragSource(); DragManager.doDrag( button, dragSource, event ); // Accept dragDrop if ( acceptDragDropCheckBox.selected ) { DragManager.acceptDragDrop( this ); } // Avoid error if ( avoidErrorCheckBox.selected ) { button.dispatchEvent( new MouseEvent( MouseEvent.MOUSE_MOVE, true,false, button.mouseX, button.mouseY ) ); } } protected function errorHandler( e : UncaughtErrorEvent ) : void { Alert.show("An error has occurred and been caught by the global error handler: " + String( e.error ), "My Global Error Handler"); e.preventDefault(); } ]]> </fx:Script> <s:Label x="20" y="10" text="If you accept dragDrop you need to avoid the error!"/> <s:CheckBox id="acceptDragDropCheckBox" x="20" y="30" label="Accept DragDrop"/> <s:CheckBox id="avoidErrorCheckBox" x="20" y="50" label="Avoid error"/> <mx:Button id="dragButton" x="20" y="110" mouseDown="onButtonMouseDown(event)" label="Drag me. Or click me for error!"/> </s:Application>
UPDATE:
A much better way to avoid this error is listening to a DragEvent.DRAG_ENTER
before calling DragManager.acceptDragDrop()
:
<?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" dragEnter="dragEnterDataRenderer(event)" height="100%" width="100%"> <fx:Script> <![CDATA[ import mx.core.DragSource; import mx.core.UIComponent; import mx.events.DragEvent; import mx.managers.DragManager; private function onButtonMouseDown( event : MouseEvent ) : void { var button : UIComponent = UIComponent( event.target ); var dragSource:DragSource = new DragSource(); DragManager.doDrag( button, dragSource, event ); } private function dragEnterDataRenderer( event : DragEvent ) : void { DragManager.acceptDragDrop( this ); } ]]> </fx:Script> <mx:Button id="dragButton" x="20" y="20" mouseDown="onButtonMouseDown(event)" label="Click me. Drag me. No Error."/> </s:Application>