5

一旦我打电话DragManager.acceptDrag,有什么办法可以“不接受”拖累吗?假设我有一个可以接受拖放的视图,但仅限于某些区域。一旦用户拖动我调用的这些区域之一DragManager.acceptDrag(this)(从DragEvent.DRAG_OVER处理程序),但如果用户随后移出该区域,我想将拖动的状态更改为不接受并显示DragManager.NONE反馈。但是,无论调用DragManager.acceptDrag(null)还是DragManager.showFeedback(DragManager.NONE)似乎都没有任何效果。一旦我接受了拖动设置反馈类型,我似乎无法更改它。

明确一点:用户应该能够放置的区域不是组件,甚至不是显示对象,实际上它们只是文本字段文本中的范围(如选择)。如果他们是他们自己的组件,我可以通过让他们每个人单独接受拖动事件来解决它。我想我可以创建漂浮在文本上的代理组件来模拟它,但如果没有必要,我宁愿不这样做。


我现在已经设法让它在 AIR 和浏览器中工作,但只能通过将代理组件放在应该能够放置内容的文本范围的顶部。这样我就得到了正确的反馈,并且在拖动退出时会自动不接受下降。

这是 AIR 中关于 D&D 最奇怪的事情:

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

在基于浏览器的 Flex 中,offsetX应该offsetY是负数(文档如是说,它工作正常)。但是,当在 AIR 中运行完全相同的代码时,您必须使偏移量为正。相同的数字,但为正数。这是非常非常奇怪的。


我已经测试了更多以及@maclema 的工作原理,但如果你在 AIR 中运行则不行。AIR中的拖放似乎有所不同。这真的很奇怪,因为不仅反馈没有正确显示,而且不可能不接受,而且坐标也完全关闭了。我只是在浏览器而不是 AIR 中尝试了我的应用程序,并且拖放完全被破坏了。

此外,跳过dragEnter处理程序在 AIR 中工作正常,但在浏览器中运行时会破坏一切。

4

5 回答 5

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>
于 2008-08-14T15:29:51.070 回答
1

如果您不需要 AIR 中的原生拖放,则可以通过子类化 WindowedApplication 并设置 DragManager 来获得 Flex 拖放行为。有关更多信息,请参阅 Adob​​e Jira 上的此帖子:https ://bugs.adobe.com/jira/browse/SDK-13983

于 2008-09-18T05:37:31.300 回答
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.
    }
    
于 2013-02-21T18:41:51.117 回答
0

Yes, drag and drop is different in AIR. I HATE that! It takes a lot of playing around to figure out how to get things to work the same as custom dnd that was built in flex.

As for the coordinates, maybe play around with localToContent, and localToGlobal methods. They may help in translating the coordinates to something useful.

Good luck. I will let you know if I think of anything else.

于 2008-08-19T15:16:08.433 回答
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>
于 2008-08-15T17:57:40.840 回答