PDA

Просмотр полной версии : Перетаскивание элементов внутри Tree - как выяснить, что куда перетащили?


Gaen
06.10.2009, 00:54
Компонент Tree позволяет перетаскивать элементы между папками, при этом элементы перемещаются туда, куда их перетащили. Как узнать, какой элемент куда перетащили? Это нужно для того, чтобы отправить на сервер запрос о перемещении элемента из одной категории в другую.

wvxvw
06.10.2009, 01:59
Не пробуя, на угад:
подписаться на dragComplete / paste, у евента dragSource будет по идее перетаскиваемым объектом... И потом через getParentItem() отыскать куда он упал. Вопрос в том, что именно вы подразумеваете под "куда перетащили", вполне возможно, что будет менее затратно просто сравнить XML (если провайдер XML) до и после.

Gaen
06.10.2009, 04:49
После долгого вдумчивого чтения кода Tree пришёл к вот такому решению:

this.structureTree.calculateDropIndex(e);

var dd :Object = this.structureTree.mx_internal::_dropData;

if(dd.parent)trace(dd.parent.@title); else trace('root');


У этого компонента есть очень полезная функция updateDropData, которая вычисляет и буквально приносит на блюдечке много чего полезного, в том числе ссылку на текущий родительский элемент. Правда блюдечко это находится в пространстве mx_internal, а сама функция приватная :) Но зато есть функция calculateDropIndex, которая фактически её и вызывает. Теперь всё в ажуре: сравниваем parent до и после перетаскивания и делаем что хотим.

Добавлено через 1 час 14 минут
И только потом наткнулся на метод getParentItem.

Пойду-ка я спать лучше.

WhiteWoolf
14.10.2009, 19:30
Господа, боюсь, что я присоединяюсь к вопросу, и никак не могу удовлетвориться ответом. Если можно, чуть-чуть подробнее.
Конкретно, задача очень простая. Есть dataprovider (XMLList):
<mx:XMLList id="treeData">
<node szName="Mail Box" szIndex="1">
<node szName="Inbox" szIndex="2">
<node szName="Marketing" szIndex="3"/>
<node szName="Product Management" szIndex="4"/>
<node szName="Personal" szIndex="5"/>
</node>
<node szName="Outbox" szIndex="6">
<node szName="Professional" szIndex="7"/>
<node szName="Personal" szIndex="8"/>
</node>
<node szName="Spam" szIndex="9"/>
<node szName="Sent" szIndex="10"/>
</node>
</mx:XMLList>

Он подцеплен к дереву, и поле szName выводится в качестве labelField. Т.е. как-то так:
<mx:Tree id="theTreeCtrl" labelField="@szName" showRoot="false"
dataProvider="{treeData}" dragEnabled="true" dropEnabled="true"
dragDrop="handlerDragDrop(event)"/>
(Код на ходу упрощал, так что если есть мелкие нестыковки - извиняйте ...)
Инициированный Drag and Drop великолепно работает. Но при окончательной обработке требуется провести ряд действий с атрибутами szIndex из соответсвующих элементов дерева. Я легко достаю этот атрибут из элемента КОТОРЫЙ перетаскивается. Выглядит это примерно так:
protected function handlerDragDrop(theEvent:DragEvent):void{
var myData:Array = theEvent.dragSource.dataForFormat("treeItems") as Array;
var szIndexSource:String = myData[0].@szIndex;

return;
}

А как добраться до этого же значения элемента, на который его бросили? Т.е. Я определяю номер его строки на экране (с учетом открытых и схлопнутых веток)
var nLine:int = theTreeCtrl.calculateDropIndex(theEvent);
А чего с ним делать дальше? Как добраться до DataProvider-а, а точнее до нужного элемента в нем?

Заранее, спасибо.

Добавлено через 15 часов 44 минуты
Если кому еще интересна эта тема, я все таки разобрался. Полученный через calculateDropIndex индекс следует присвоить в selectedIndex и тогда из selectedItem можно будет извлекать необходимые значения.
Побочный эффект данного решения в том, что смещается выделение в дереве и не совсем понятно поведение при множественном выделении. Однако как базовое решение - вполне пригодно.
Итого: для работы с данными элемента на который брошен перетаскиваемый элемент следует писать:
var nLine:int = theTreeCtrl.calculateDropIndex(theEvent);
theTreeCtrl.selectedIndex = nLine;
var szIndexDestinct:String = theTreeCtrl.selectedItem.@szIndex;