【问题标题】:Find out which tree item has been dropped on to in Flex在 Flex 中找出哪个树项目已被拖放到
【发布时间】:2011-08-13 03:42:39
【问题描述】:

我有一个 mx.List 和一个 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.Tree 项目渲染器: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" />

需要做一些工作来整理视觉反馈,但这应该会输出被拖放到的 Tree 项目。

【问题讨论】:

    标签: apache-flex list drag-and-drop tree components


    【解决方案1】:

    关于

    var source:List = event.dragInitiator as List;
    var target:List = event.currentTarget as List;
    

    尝试检查您的进口。也许有导入的 Spark 列表,但您使用的是 MX 列表? :)

    关于dropTarget 属性请参考documentation about it。它与 Flex 拖放功能无关。所以这个属性的值为 null 也就不足为奇了。

    你的问题一般你可以使用下面的sn-p,它不能解决所有问题(我没有时间调试所有方面)但可以为你提供一些好的起点:

    <?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 && 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>
    

    【讨论】:

    • @Constantiner 是的。 var source:mx.controls.List = event.dragInitiator as mx.controls.List; var target:mx.controls.List = event.currentTarget as mx.controls.List;
    • 附注的答案是正确的,而不是关键问题。
    • @Constantiner 我的帖子的主要重点是发现 Tree/List 组件中的哪个元素被拖放到 - 我还没有答案。作为一个旁注,当我将event.dragInitiatorevent.currentTarget 转换为 List 时,我提到了一个错误(第一个代码块将它们设为未键入)。您对附注的回复是正确的,但帖子的主要焦点 Find out which tree item has been dropped to in Flex 仍未得到答复。
    猜你喜欢
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-04
    • 1970-01-01
    • 2010-12-24
    • 2016-03-26
    • 2012-03-27
    相关资源
    最近更新 更多