Если я <вызвал DragManager.acceptDrag
, есть ли способ "отменить" перетаскивание? Скажем, у меня есть представление, которое может принимать перетаскивание, но только в определенных областях. Когда пользователь перетаскивает одну из этих областей, я вызываю DragManager.acceptDrag(this)
(из обработчика DragEvent.DRAG_OVER
), но если пользователь затем выходит из этой области, я'хотел бы изменить статус перетаскивания на непринятый и показать DragManager.NONE
сообщение. Однако, ни вызов DragManager.acceptDrag(null)
, ни DragManager.showFeedback(DragManager.NONE)
не дают никакого эффекта. После того, как я принял перетаскивание и установил тип обратной связи, я не могу изменить его.
Для ясности: области, куда пользователь должен иметь возможность перетаскивать, не являются компонентами или даже объектами отображения, фактически это просто диапазоны в тексте текстового поля (как и выделение). Если бы они были самостоятельными компонентами, я мог бы решить эту проблему, заставив каждую из них принимать события перетаскивания по отдельности. Думаю, я мог бы создать прокси-компоненты, которые парят над текстом, чтобы имитировать это, но я не хотел бы этого делать, если в этом нет необходимости.
Сейчас мне удалось заставить его работать и в AIR, и в браузере, но только путем размещения прокси-компонентов поверх диапазонов текста, где вы должны иметь возможность опускать предметы. Таким образом я получаю правильную обратную связь, и падения автоматически не принимаются при выходе из перетаскивания.
Это самая странная вещь в D&D в AIR:
DragManager.doDrag(initiator, source, event, dragImage, offsetX, offsetY);
В браузерном Flex, offsetX
и offsetY
должны быть отрицательными (так говорится в документации, и это прекрасно работает). Однако при выполнении точно такого же кода в AIR необходимо сделать смещения положительными. Те же числа, но положительными. Это очень, очень странно.
Я'протестировал еще немного и то, что @maclema работает, но не если вы запускаете в AIR. Похоже, что перетаскивание в AIR отличается. Это очень, очень странно, потому что не только обратная связь не отображается правильно, и невозможно отменить прием, но и координаты полностью не совпадают. Я только что попробовал свое приложение в браузере вместо AIR, и перетаскивание полностью сломалось.
Кроме того, пропуск обработчика dragEnter
работает нормально в AIR, но ломает все при запуске в браузере.
Вы используете только метод 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>
Если вы Don'т нужна родная перетащить в воздухе, вы можете получить гибкий перетаскивания на подклассы WindowedApplication и параметр метода dragmanager. Вижу этот пост на Adobe JIRA в более подробная информация: https://bugs.adobe.com/jira/browse/SDK-13983
Вы неправильно поняли концепцию. Вашу "пойдет", которая достигается путем реализации dragOverHandler и сигнализирующая о том, что данные не хотели.
Вот основная концепция:
dragEnterHandler функция(событие: DragEvent):пустота { если (данные апартаменты как минимум одно место в этом компоненте) Метода dragmanager.acceptDragDrop(это); }
Это позволяет контейнеру получать дальнейшие сообщения (dragover встречает/dragExit). Но это не на месте решить, какой вид курсора мыши должны быть показаны.
Без Метода Dragmanager.acceptDragDrop(этого); другие обработчики не'т называется.
dragOverHandler функция(событие: DragEvent):пустота { если (данные апартаменты как минимум не место в этом компоненте) { Метода dragmanager.showFeedback(метода dragmanager.Нет); возврат; }
... // обрабатываем другие случаи и показать значок курсора / вы хотите }
Звоню Метода Dragmanager.showFeedback(метода dragmanager.Нет); делает трюк для отображения "не пойдет" по.
dragOverHandler функция(событие: DragEvent):пустота { // обрабатываем полученные данные, как вам нравится. }
Хорошо, теперь я вижу проблему. Вместо 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>
Да, перетаскивание в AIR отличается. Я ненавижу это! Приходится много играть, чтобы понять, как заставить все работать так же, как в пользовательском dnd, который был создан во flex.
Что касается координат, возможно, поиграйте с методами localToContent и localToGlobal. Они могут помочь в преобразовании координат во что-то полезное.
Удачи. Я дам вам знать, если вспомню что-нибудь еще.