代码之家  ›  专栏  ›  技术社区  ›  Theo

我怎样才能“不接受”Flex中的拖拽?

  •  5
  • Theo  · 技术社区  · 16 年前

    一旦我打过电话 DragManager.acceptDrag DragManager.acceptDrag(this) (来自 DragEvent.DRAG_OVER 处理程序),但如果用户随后移出此区域,我希望将拖动的状态更改为“不接受”,并显示 DragManager.NONE DragManager.acceptDrag(null) DragManager.showFeedback(DragManager.NONE) 似乎有效果。一旦我接受了拖拽集的反馈类型,我似乎无法改变它。

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


    我已经设法让它在AIR和浏览器中都能正常工作了,但只是把代理组件放在文本范围的顶部,这样你就可以放下东西了。这样我就得到了正确的反馈,并且在拖动退出时自动不接受。

    这是空气中D&D最奇怪的地方:

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

    offsetX offsetY 完全相同的代码 在空中你必须使偏移量为正。相同的数字,但是是正的。这太奇怪了。


    我又测试了些什么 @maclema 有效,但如果你在空中奔跑就不行了。似乎空气中的拖放是不同的。这真的很奇怪,因为不仅反馈没有正确显示,而且不可能不被接受,而且坐标也完全关闭了。我只是在浏览器中尝试了我的应用程序而不是AIR,拖放操作完全失败了。

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

    5 回复  |  直到 8 年前
        1
  •  6
  •   Matt MacLean    16 年前

    <?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>
    
        3
  •  1
  •   bebbo    12 年前

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

    基本概念如下:

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

      这使您的容器能够接收更多消息(dragOver/dragExit)。但这是

      没有 不调用其他处理程序。

    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
      }
      

      打电话 显示“不合格”的诀窍。

    3. 注册dragExitHandler或重写已注册的方法。

      function dragOverHandler(event: DragEvent):void {
          // handle the recieved data as you like.
      }
      
        4
  •  0
  •   Matt MacLean    16 年前

    好吧,我现在明白问题所在了。尝试将其设置为draginInitiator,而不是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>
    
        5
  •  0
  •   Matt MacLean    16 年前

    至于坐标,可以使用localToContent和localToGlobal方法。它们可能有助于把坐标转换成有用的东西。

    祝你好运。如果我有别的想法,我会告诉你的。

    推荐文章