Как ограничить перетаскивание узлов дерева из их текущего узла в flex 3? - PullRequest
4 голосов
/ 13 ноября 2008

Итак, у меня есть компонент flex-дерева с xmllistcollection в качестве поставщика данных. Я хотел бы иметь возможность переставить листья и ветви на дереве с помощью перетаскивания. Я хочу ограничить область перетаскивания текущим уровнем перетаскиваемого элемента. подобно

      branch
       branch 0
         leaf 1
         leaf 2
       branch x
         leaf a
         leaf b
       
Таким образом, ветвь x не может быть перемещена под ветвь 0, а лист a не может быть перемещен под ветвь 0.

1 Ответ

4 голосов
/ 14 ноября 2008

Хорошо, вот довольно простой способ сделать это, основываясь на последнем примере в этой статье Flex Quick Starts . Это, вероятно, следует улучшить, используя «правильные» индикаторы перетаскивания (линии между элементами) вместо простого выбора элемента под мышью при перетаскивании.

Самая важная часть - это метод onDragOver(), где мы ограничиваем место, куда можно бросать предметы.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
        <![CDATA[

            import mx.events.DragEvent;
            import mx.managers.DragManager;
            import mx.core.DragSource;
            import mx.core.UIComponent;
            import mx.controls.Tree;

            private var _draggedItem:XML = null;


            private function onDragEnter( event:DragEvent ) : void
            {
                event.preventDefault();
                event.currentTarget.hideDropFeedback(event);

                var ds:DragSource = event.dragSource;
                var items:Array = ds.dataForFormat("treeItems") as Array;
                if (items != null && items.length > 0 && (items[0] is XML))
                    _draggedItem = items[0];

                DragManager.acceptDragDrop(UIComponent(event.currentTarget));
            }

            private function onDragOver( event:DragEvent ) : void
            {
                event.preventDefault();
                event.currentTarget.hideDropFeedback(event);

                tree.selectedIndex = tree.calculateDropIndex(event);
                var node:XML = tree.selectedItem as XML;

                // restrict drag & drop to nodes within same parent
                if (_draggedItem.parent() != node.parent())
                {
                    DragManager.showFeedback(DragManager.NONE);
                    return;
                }

                DragManager.showFeedback(DragManager.MOVE);
            }

            private function onDragDrop( event:DragEvent ) : void
            {
                event.preventDefault();
                event.currentTarget.hideDropFeedback(event);

                tree.selectedIndex = tree.calculateDropIndex(event);
                var node:XML = tree.selectedItem as XML;

                var addToIndex:int = node.childIndex();
                if ((_draggedItem.parent() == node.parent()) && (addToIndex != _draggedItem.childIndex()))
                {
                    tree.dataDescriptor.removeChildAt(node.parent(), _draggedItem, _draggedItem.childIndex());
                    tree.dataDescriptor.addChildAt(node.parent(), _draggedItem, addToIndex);
                }
            }

            private function onDragComplete( event:DragEvent ) : void
            {
                tree.selectedIndex = -1;
            }    
        ]]>
    </mx:Script>    
    <mx:XML id="treeData" xmlns="">
        <root>
            <node label="Massachusetts" type="state" data="MA">
                <node label="Boston" type="city" >
                    <node label="Smoke House Grill" type="restaurant" />
                    <node label="Equator" type="restaurant" />
                    <node label="Aquataine" type="restaurant" />
                    <node label="Grill 23" type="restaurant" />
                </node>
                <node label="Provincetown" type="city" >
                    <node label="Lobster Pot" type="restaurant" />
                    <node label="The Mews" type="restaurant" />
                </node>
            </node>
            <node label="California" type="state" data="CA">
                <node label="San Francisco" type="city" >
                    <node label="Frog Lane" type="restaurant" />
                </node>
            </node>
        </root>
    </mx:XML>
    <mx:Tree width="100%" height="100%" id="tree"
        labelField="@label"
        dataProvider="{treeData.node}"
        allowMultipleSelection="false"
        dragEnabled="true"
        dropEnabled="true"
        dragMoveEnabled="false"
        dragEnter="onDragEnter(event)"
        dragOver="onDragOver(event)"
        dragDrop="onDragDrop(event)"
        dragComplete="onDragComplete(event)">
    </mx:Tree>        
</mx:Application>
...