2008-08-14 68 views
5

一旦我打电话给DragManager.acceptDrag有没有办法“不接受”拖拽?说我有一个可以接受拖放的视图,但只能在某些区域。一旦用户拖过这些区域之一,我会呼叫DragManager.acceptDrag(this)(来自DragEvent.DRAG_OVER处理程序),但如果用户然后移出此区域,我想将拖动的状态更改为不被接受,并显示DragManager.NONE反馈。然而,拨打DragManager.acceptDrag(null)DragManager.showFeedback(DragManager.NONE)似乎都没有任何影响。一旦我接受了拖动设置反馈类型,我似乎无法改变它。如何“不接受”Flex中的拖动?

为了说清楚:用户应该能够放下的区域不是组件或甚至显示对象,实际上它们只是文本字段文本中的范围(如选区)。如果他们是他们自己的组成部分,我可以通过让他们每个人单独接受拖动事件来解决它。我想我可以创建浮动在文本上的代理组件来模拟它,但是如果没有必要,我宁愿不要。


我设法得到它在空气和浏览器现在的工作,但只有通过把代理组件上的文本的范围,你应该能够删除的东西之上。这样我就可以得到正确的反馈信息,并且在拖动退出时自动拒绝丢弃。

这是关于d & d最奇怪的事情在AIR:

DragManager.doDrag(initiator, source, event, dragImage, offsetX, offsetY); 

在基于浏览器的Flex,offsetXoffsetY应该是负的(所以文件说,它工作正常)。但是,在AIR中运行完全相同的代码时,必须将偏移量设置为正值。相同的数字,但积极的。这非常非常奇怪。


我测试过一些什么@maclema作品,但如果你在AIR运行。在AIR中拖放看起来不同。这真的很奇怪,因为反馈不仅显示不正确,而且也不可能不接受,但坐标也完全关闭。我只是在浏览器中尝试我的应用程序而不是AIR,并且拖放完全打破。

此外,跳过dragEnter处理程序在AIR中正常工作,但在浏览器中运行时会中断所有处理。

回答

6

您是否仅使用dragEnter方法?如果您尝试在拖动相同组件时拒绝拖动,则需要同时使用dragEnter和dragOver方法。

看看这个例子:

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> 
    <mx:Script> 
     <![CDATA[ 
      import mx.core.DragSource; 
      import mx.managers.DragManager; 
      import mx.events.DragEvent; 

      private function onDragEnter(e:DragEvent):void { 
       if (e.target == lbl) { 

        if (e.localX < lbl.width/2) { 
         trace("accept"); 
         DragManager.acceptDragDrop(this); 
        } 
        else { 
         DragManager.acceptDragDrop(null); 
        } 
       } 
      } 

      private function doStartDrag(e:MouseEvent):void { 
       if (e.buttonDown) { 
        var ds:DragSource = new DragSource(); 
        ds.addData("test", "text"); 

        DragManager.doDrag(btn, ds, e); 
       } 
      } 
     ]]> 
    </mx:Script> 
    <mx:Label id="lbl" text="hello world!" left="10" top="10" dragEnter="onDragEnter(event)" dragOver="onDragEnter(event)" /> 
    <mx:Button id="btn" x="47" y="255" label="Button" mouseMove="doStartDrag(event)"/> 
</mx:Application> 
+0

上接受`DRAG_ENTER`处理器的阻力只会让事情变得更糟。我仍然不能拒绝拖动(调用`DragManager.acceptDragDrop(null)`没有效果,至少没有可见的效果),并接受输入拖动删除我有的小控制。鼠标进入组件后,鼠标立即显示指针下方的+,而不是在用户拖过特殊区域时开始显示。 – Theo 2008-08-14 16:26:15

0

好了,我现在看到的问题。尝试将其设置为dragInitiator,而不是null。

看看这个。

<?xml version="1.0" encoding="utf-8"?> 
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> 
    <mx:Script> 
     <![CDATA[ 
      import mx.controls.Alert; 
      import mx.events.DragEvent; 
      import mx.managers.DragManager; 
      import mx.core.DragSource; 

      private function doStartDrag(e:MouseEvent):void { 
       if (e.buttonDown && !DragManager.isDragging) { 
       var ds:DragSource = new DragSource(); 
       ds.addData("test", "test"); 

       DragManager.doDrag(btn, ds, e); 
       } 
      } 

      private function handleDragOver(e:DragEvent):void { 
       if (e.localX < cvs.width/2) { 
        //since null does nothing, lets just set to accept the drag 
        //operation, but accept it to the dragInitiator 
        DragManager.acceptDragDrop(e.dragInitiator); 
       } 
       else { 
        //accept drag 
        DragManager.acceptDragDrop(cvs); 
        DragManager.showFeedback(DragManager.COPY); 
       } 
      } 

      private function handleDragDrop(e:DragEvent):void { 
       if (e.dragSource.hasFormat("test")) { 
        Alert.show("Got a drag drop!"); 
       } 
      } 
     ]]> 
    </mx:Script> 
    <mx:Canvas x="265" y="66" width="321" height="245" backgroundColor="#FF0000" id="cvs" dragOver="handleDragOver(event)" dragDrop="handleDragDrop(event)"> 
    </mx:Canvas> 
    <mx:Button id="btn" x="82" y="140" label="Drag Me" mouseDown="doStartDrag(event)"/> 
</mx:WindowedApplication> 
0

是的,拖放在AIR中是不同的。我讨厌那个!需要花费大量的时间来弄清楚如何让事情像在flex中构建的自定义dnd一样工作。

至于坐标,也许玩弄localToContent和localToGlobal方法。他们可能有助于将坐标转换为有用的东西。

好运。如果我想到其他事情,我会让你知道的。

1

如果您不需要在AIR中进行本机拖放,则可以通过继承WindowedApplication并设置DragManager来获得Flex拖放行为。有关更多信息,请参阅Adobe Jira上的此帖:https://bugs.adobe.com/jira/browse/SDK-13983

1

您误解了这个概念。您的“不接受”是通过实施dragOverHandler并发信号通知不需要数据来实现的。

这里的基本概念:

  1. 注册dragEnterHandler或重写已经注册方法。

    function dragEnterHandler(event: DragEvent):void { 
        if (data suites at least one location in this component) 
         DragManager.acceptDragDrop(this); 
    } 
    

    这使您的容器能够接收更多消息(dragOver/dragExit)。但是这是不是决定应该显示哪种鼠标光标的位置。

    没有DragManager.acceptDragDrop(this);其他处理程序不被调用。

  2. 注册dragOverHandler或覆盖已注册的方法。

    function dragOverHandler(event: DragEvent):void { 
        if (data suites at least no location in this component) { 
         DragManager.showFeedback(DragManager.NONE); 
         return; 
        } 
    
        ... // handle other cases and show the cursor/icon you want 
    } 
    

    调用DragManager.showFeedback(DragManager.NONE);会诀窍显示“不接受”。

  3. 注册dragExitHandler或覆盖已注册的方法。

    function dragOverHandler(event: DragEvent):void { 
        // handle the recieved data as you like. 
    }