#apache-flex #list #drag-and-drop #tree #components
#apache-flex #Список #перетаскивание #дерево #Компоненты
Вопрос:
У меня есть mx.Список и mx.Tree. Я пытаюсь перетащить элементы из списка в дерево, но вместо того, чтобы добавлять их в собственно само дерево, я просто хочу выяснить, что такое DropTarget в дереве. Переменная DropTarget всегда null
.
protected function sparkTree_dragDropHandler(event:DragEvent):void
{
var source:* = event.dragInitiator;
var target:* = event.currentTarget;
trace("Dragged......", source.selectedItem.label);
trace("From.........", source.name);
trace("To...........", event.currentTarget.name);
trace("Target Item..", event.currentTarget.dropTarget);
}
Вывод:
Dragged...... itemOne
From......... _Main_Tree2
To........... _Main_Tree1
Target Item.. null
Итак, просто чтобы уточнить, я пытаюсь получить объект, на который сбрасываются элементы.
В качестве дополнительного примечания, используя:
var source:List = event.dragInitiator as List;
var target:List = event.currentTarget as List;
в результате ошибка с нулевой ссылкой на объект. Кажется странным?
Обновить:
(Не уверен, где лучшее место для публикации этого, но) Я думаю, что это может быть решением…
Создайте пользовательское событие: ItemDragEvent
package events
{
import mx.core.DragSource;
import mx.core.IUIComponent;
import mx.events.DragEvent;
public class ItemDragEvent extends DragEvent
{
public static const DRAG_DROP:String = "itemDragDrop";
public static const DRAG_ENTER:String = "itemDragEnter";
public static const DRAG_EXIT:String = "itemDragExit";
public var item:Object;
public var data:Object;
public var index:Object;
public function ItemDragEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=true, dragInitiator:IUIComponent=null, dragSource:DragSource=null, action:String=null, ctrlKey:Boolean=false, altKey:Boolean=false, shiftKey:Boolean=false)
{
super(type, bubbles, cancelable, dragInitiator, dragSource, action, ctrlKey, altKey, shiftKey);
}
}
}
Создайте mx.Средство визуализации элементов дерева: TreeItemRenderer
<?xml version="1.0" encoding="utf-8"?>
<s:MXTreeItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
dragEnter="dragEnterHandler(event)"
dragExit="dragExitHandler(event)"
dragDrop="dragDropHandler(event)"
>
<fx:Script>
<![CDATA[
import events.ItemDragEvent;
import mx.core.IUIComponent;
import mx.events.DragEvent;
import mx.managers.DragManager;
protected function dragEnterHandler(event:DragEvent):void
{
DragManager.acceptDragDrop(event.currentTarget as IUIComponent);
var e:ItemDragEvent = new ItemDragEvent(ItemDragEvent.DRAG_ENTER, true);
e.data = data;
e.item = data;
e.index = itemIndex;
dispatchEvent(e);
trace("TreeItemRenderer, dragEnterHandler");
}
protected function dragExitHandler(event:DragEvent):void
{
var e:ItemDragEvent = new ItemDragEvent(ItemDragEvent.DRAG_EXIT, true);
e.data = data;
e.item = data;
e.index = itemIndex;
dispatchEvent(e);
trace("TreeItemRenderer, dragExitHandler");
}
protected function dragDropHandler(event:DragEvent):void
{
DragManager.acceptDragDrop(event.currentTarget as IUIComponent);
var e:ItemDragEvent = new ItemDragEvent(ItemDragEvent.DRAG_DROP, true);
e.data = data;
e.item = data;
e.index = itemIndex;
dispatchEvent(e);
trace("TreeItemRenderer, dragDropHandler");
}
]]>
</fx:Script>
<s:states>
<s:State name="normal" />
<s:State name="hovered" />
<s:State name="selected" />
</s:states>
<s:HGroup left="0" right="0" top="0" bottom="0" verticalAlign="middle">
<s:Rect id="indentationSpacer" width="{treeListData.indent}" percentHeight="100" alpha="0">
<s:fill>
<s:SolidColor color="0xFFFFFF" />
</s:fill>
</s:Rect>
<s:Group id="disclosureGroup">
<s:BitmapImage source="{treeListData.disclosureIcon}" visible="{treeListData.hasChildren}" />
</s:Group>
<s:BitmapImage source="{treeListData.icon}" />
<s:Label id="labelField" text="{treeListData.label}" paddingTop="2"/>
</s:HGroup>
</s:MXTreeItemRenderer>
Наконец, основной код
</fx:Declarations>
<fx:Script>
<![CDATA[
import events.ItemDragEvent;
import itemRenderers.TreeItemRenderer;
import mx.collections.ArrayCollection;
import mx.events.DragEvent;
import mx.events.FlexEvent;
import mx.utils.ObjectUtil;
[Bindable]
private var listData:ArrayCollection = new ArrayCollection([ "One", "Two", "Three" ]);
[Bindable]
private var treeData:Object = { label: "First", children: new ArrayCollection([ { label: "Second" }, { label: "Third" } ]) };
protected function windowedapplication1_initializeHandler(event:FlexEvent):void
{
tree1.addEventListener(ItemDragEvent.DRAG_DROP, treeItemDragDropHandler);
}
protected function treeItemDragDropHandler(event:ItemDragEvent):void
{
event.preventDefault();
trace("ItemDragDrop:", ObjectUtil.toString(event.data));
}
]]>
</fx:Script>
<s:layout>
<s:HorizontalLayout horizontalAlign="center" verticalAlign="middle" />
</s:layout>
<mx:Tree id="list1" width="50%" height="100%"
dataProvider="{listData}" labelField="label"
dragEnabled="true"
dragMoveEnabled="true"
dropEnabled="true" />
<mx:Tree id="tree1" width="50%" height="100%"
dataProvider="{treeData}"
dragEnabled="true"
dropEnabled="true"
showRoot="true"
itemRenderer="itemRenderers.TreeItemRenderer" />
Требуется небольшая работа для сортировки визуальной обратной связи, но это должно вывести элемент дерева, на который был удален.
Ответ №1:
Что касается
var source:List = event.dragInitiator as List;
var target:List = event.currentTarget as List;
Попробуйте проверить свой импорт. Может быть, были импортированы списки Spark, но вы используете MX List ? 🙂
Что касается dropTarget
свойства, пожалуйста, обратитесь к документации о нем. Это не относится к функциональности Flex drag-n-drop. И поэтому неудивительно, что значение этого свойства равно null.
Что касается вашей проблемы в целом, вы можете использовать следующий фрагмент, который не решает всех проблем (у меня нет времени на отладку всех аспектов), но может предоставить вам хорошую отправную точку:
<?xml version="1.0" encoding="utf-8"?>
<s:Application minHeight="600" minWidth="955" xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.collections.ICollectionView;
import mx.events.DragEvent;
import mx.managers.DragManager;
[Bindable]
private var listDataProvider:ArrayCollection = new ArrayCollection([ "First", "Second", "Third" ]);
[Bindable]
private var treeDataProvider:Object =
{ label: "First", children: new ArrayCollection([ { label: "Second" }, { label: "Third" } ]) };
protected function list_dragCompleteHandler(event:DragEvent):void
{
if (event.relatedObject == tree)
{
event.preventDefault();
if (event.action == DragManager.MOVE amp;amp; list.dragMoveEnabled)
{
var items:Array = event.dragSource.dataForFormat("items") as Array;
var collection:ArrayCollection = list.dataProvider as ArrayCollection;
for each (var item:Object in items)
{
if (collection.contains(item))
collection.removeItemAt(collection.getItemIndex(item));
}
}
}
}
protected function tree_dragDropHandler(event:DragEvent):void
{
var source:List = List(event.dragInitiator);
var target:Tree = Tree(event.currentTarget);
trace("Dragged......", source.selectedItem);
trace("From.........", source.name);
trace("To...........", target.name);
event.preventDefault();
tree.hideDropFeedback(event);
var index:int = tree.calculateDropIndex(event);
var items:Array = new Array();
if (event.dragSource.hasFormat("treeItems"))
items = items.concat(event.dragSource.dataForFormat("treeItems") as Array);
if (event.dragSource.hasFormat("items"))
items = items.concat(event.dragSource.dataForFormat("items") as Array);
if (index > (tree.dataProvider as ICollectionView).length)
index = (tree.dataProvider as ICollectionView).length;
for each (var item:Object in items)
{
var obj:Object = new Object()
obj.label = item;
(tree.dataProvider as ArrayCollection).addItemAt(obj, index);
}
}
protected function tree_dragEnterHandler(event:DragEvent):void
{
if (event.dragInitiator == list)
{
event.preventDefault();
DragManager.acceptDragDrop(event.target as Tree);
tree.showDropFeedback(event);
}
}
protected function tree_dragExitHandler(event:DragEvent):void
{
event.preventDefault();
tree.hideDropFeedback(event);
}
protected function tree_dragOverHandler(event:DragEvent):void
{
if (event.dragInitiator == list)
{
event.preventDefault();
tree.showDropFeedback(event);
}
}
]]>
</fx:Script>
<s:layout>
<s:HorizontalLayout horizontalAlign="center" verticalAlign="middle" />
</s:layout>
<mx:List dataProvider="{listDataProvider}" dragComplete="list_dragCompleteHandler(event)" dragEnabled="true"
dragMoveEnabled="true" dropEnabled="true" id="list" width="200" />
<mx:Tree dataProvider="{treeDataProvider}" dragDrop="tree_dragDropHandler(event)" dragEnabled="true"
dragEnter="tree_dragEnterHandler(event)" dragExit="tree_dragExitHandler(event)"
dragOver="tree_dragOverHandler(event)" dropEnabled="true" id="tree" showRoot="true" width="200" />
</s:Application>
Комментарии:
1. @Constantiner Да.
var source:mx.controls.List = event.dragInitiator as mx.controls.List; var target:mx.controls.List = event.currentTarget as mx.controls.List;
2. Ответ на примечание сбоку был правильным, а не на ключевой вопрос.
3. @Constantiner Основной целью моего поста было выяснить, на какой элемент в компоненте Tree / List был перенесен — у меня пока нет ответа на это. В качестве дополнительного примечания я упомянул, что когда я приводил список
event.dragInitiator
иevent.currentTarget
as, я получал сообщение об ошибке (в первом блоке кода они указаны как нетипизированные). Ваш ответ на боковое примечание был правильным, но основная цель сообщения Выяснить, на какой элемент дерева был перенесен в Flex , остается без ответа.