5

呼び出した後DragManager.acceptDrag、ドラッグを「受け入れない」方法はありますか? ドラッグアンドドロップを受け入れることができるビューがあるとしますが、特定の領域のみです。DragManager.acceptDrag(this)ユーザーが(ハンドラーから)呼び出したこれらの領域の1つをドラッグすると、ユーザーがこの領域から移動した場合、ドラッグのステータスを受け入れられないに変更し、フィードバック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 ではoffsetXoffsetY負の値にする必要があります (ドキュメントにはそう書かれていますが、問題なく動作します)。ただし、まったく同じコードを 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

あなたはその概念を誤解しています。「不承認」は、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 に答える
1

AIRでネイティブのドラッグアンドドロップが必要ない場合は、WindowedApplicationをサブクラス化し、DragManagerを設定することで、Flexのドラッグアンドドロップ動作を取得できます。詳細については、Adobe Jiraのこの投稿を参照してください:https ://bugs.adobe.com/jira/browse/SDK-13983

于 2008-09-18T05:37:31.300 に答える
0

はい、AIR ではドラッグ アンド ドロップが異なります。嫌いです!flex で構築されたカスタム dnd と同じように機能させる方法を理解するには、多くの試行錯誤が必要です。

座標に関しては、localToContent および localToGlobal メソッドで遊んでみてください。座標を便利なものに変換するのに役立つ場合があります。

幸運を。また何か思いついたらお知らせします。

于 2008-08-19T15:16:08.433 に答える
0

わかりました、問題がわかりました。null ではなく、dragInitiator に設定してみてください。

これをチェックしてください。

<?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 に答える