【问题标题】:Flex AdvancedDataGrid Tree Custom DragFlex AdvancedDataGrid 树自定义拖动
【发布时间】:2009-07-20 14:55:03
【问题描述】:

我想在 AdvancedDataGrid 树结构上实现自定义拖动,它只允许在树枝(而不是叶子)上拖动。

我遇到了很多困难,尝试使用 MouseDown 事件,但没有运气!

好的,我想我已经让 mousedown 能够确定该项目是否是叶子的分支。有关如何使用高级数据网格执行自定义拖动的任何帮助?

 var grid : AdvancedDataGrid = AdvancedDataGrid(event.currentTarget);
    如果(grid.selectedItem.hasOwnProperty(“类别”)
        && grid.selectedItem.categories!=null) {
          Alert.show("是");
    }
    否则 { Alert.show("no"); }

【问题讨论】:

    标签: apache-flex tree advanceddatagrid


    【解决方案1】:

    我尝试了许多不同的方法来做到这一点,这是我想出的最佳解决方案。 AdvancedDataGrid 已经内置了处理 mouseMove/mouseOver/mouseDown 事件的逻辑,因此无需重新创建它。只需覆盖 DragEvent 处理程序。

    我已经复制了我在需要类似功能的几个应用程序中使用的代码,包括确定项目是否可以拖动的逻辑,以及确定项目是否可以放在某个位置的一些逻辑。我还包括了广泛的评论,以帮助解释为什么要完成某些事情。我希望这会有所帮助!

    CustomADG.as:

    package
    {
        import mx.controls.AdvancedDataGrid;
        import mx.controls.listClasses.IListItemRenderer;
        import mx.core.DragSource;
        import mx.events.DragEvent;
        import mx.managers.DragManager;
        import mx.utils.ObjectUtil;
    
        public class DragDropADG extends AdvancedDataGrid
        {
            private var itemRendererUnderPoint:IListItemRenderer
    
            public function DragDropADG()
            {
                super();
            }
    
            override protected function dragStartHandler(event:DragEvent):void
            {
                /* Create a new Array from the Array of selectedItems, filtering out items 
                    that are not "branches". */
                var selectedBranches:Array /* of Object */ = 
                    selectedItems.filter(hasCategories);
    
                function hasCategories(element:*, index:int, array:Array):Boolean
                {
                    /* Returns true if the item is a Branch (has children in the categories 
                        property). */
                    return (element.hasOwnProperty("categories") && 
                                    element.categories != null);
                }
    
                /* Exit if no Branches are selected. This will stop the drag operation from 
                    starting. */
                if (selectedBranches.length == 0)
                    return;
    
                /* Reset the selectedItems Array to include only selected Branches. This 
                    will deselect any "non-Branch" items. */
                selectedItems = selectedBranches;
    
                /* Create a copy of the Array of selected indices to be sorted for 
                    display in the drag proxy. */
                var sortedSelectedIndices:Array /* of int */ = 
                    ObjectUtil.copy(selectedIndices) as Array /* of int */;
    
                // Sort the selected indices
                sortedSelectedIndices.sort(Array.NUMERIC);
    
                /* Create an new Array to store the selected Branch items sorted in the 
                    order that they are displayed in the AdvancedDataGrid. */
                var draggedBranches:Array = [];
    
                var itemRendererAtIndex:IListItemRenderer;
    
                for each (var index:int in sortedSelectedIndices)
                {
                    itemRendererAtIndex = indexToItemRenderer(index);
    
                    var branchItem:Object = itemRendererAtIndex.data;
    
                    draggedBranches.push(branchItem);
                }
    
                // Create a new DragSource Object to store data about the Drag operation.
                var dragSource:DragSource = new DragSource();
    
                // Add the Array of Branches to be dragged to the DragSource Object.
                dragSource.addData(draggedBranches, "draggedBranches");
    
                // Create a new Container to serve as the Drag Proxy.
                var dragProxy:DragProxyContainer = new DragProxyContainer();
    
                /* Update the labels in the Drag Proxy using the "label" field of the items 
                    being dragged. */
                dragProxy.setLabelText(draggedBranches);
    
                /* Create a point relative to this component from the mouse 
                    cursor location (for the DragEvent). */
                var eventPoint:Point = new Point(event.localX, event.localY);
    
                // Initiate the Drag Event
                DragManager.doDrag(this, dragSource, event, dragProxy, 
                    -eventPoint.x, -eventPoint.y, 0.8);
            }
    
            /* This function runs when ANY item is dragged over any part of this 
                AdvancedDataGrid (even if the item is from another component). */
            override protected function dragEnterHandler(event:DragEvent):void 
            {
                /* If the item(s) being dragged does/do not contain dragged Branches, 
                    it/they are being dragged from another component; exit the function to 
                    prevent a drop from occurring. */
                if (!event.dragSource.hasFormat("draggedBranches"))
                    return;
    
                var dropIndex:int = calculateDropIndex(event);
    
                /* Get the itemRenderer of the current drag target, to determine if the 
                    drag target can accept a drop. */
                var dropTargetItemRenderer:IListItemRenderer = 
                    indexToItemRenderer(dropIndex);
    
                /* If the item is being dragged where there is no itemRenderer, exit the 
                    function, to prevent a drop from occurring. */ 
                if (dropTargetItemRenderer == null)
                    return;
    
                /* If the item is being dragged onto an itemRenderer with no data, exit the 
                    function, to prevent a drop from occurring. */ 
                if (dropTargetItemRenderer.data == null)
                    return;
    
                /* Store the underlying item for the itemRenderer being dragged over, to 
                    validate that it can be dropped there. */
                var dragEnterItem:Object = dropTargetItemRenderer.data
    
                if (!dragEnterItem.hasOwnProperty("categories")
                    return;
    
                if (dragEnterItem.categories == null)
                    return;
    
                var eventDragSource:DragSource = event.dragSource;
    
                eventDragSource.addData(dragEnterItem, "dropTargetItem");
    
                /* Add an dragDrop Event Listener to the itemRenderer so that the 
                    necessary will run when it is dropped.*/
                dropTargetItemRenderer.addEventListener(DragEvent.DRAG_DROP, 
                    itemRenderer_dragDropHandler);
    
                // Specify that the itemRenderer being dragged over can accept a drop.
                DragManager.acceptDragDrop(dropTargetItemRenderer);
            }
    
            /* Perform any logic that you want to occur once the user drops the item. */
            private function itemRenderer_dragDropHandler(event:DragEvent):void
            {
                var eventDragSource:DragSource = event.dragSource;
    
                var dropTargetItem:Object = 
                    eventDragSource.dataForFormat("dropTargetItem");
    
                if (dropTargetItem == null)
                    return;
    
                var draggedBranchesData:Object = 
                    eventDragSource.dataForFormat("draggedBranches");
    
                var draggedBranches:Array /* of Object */ = 
                    draggedBranchesData as Array /* of Object */;
    
                // Call any other functions to update your underlying data, etc.
            }
        }
    }
    

    DragProxyContainer.as:

    package
    {
        import mx.containers.VBox;
        import mx.core.UITextField;
    
        [Bindable]
        public class DragProxyContainer extends VBox
        {
            private var textField:UITextField = new UITextField();
    
            public function DragProxyContainer()
            {
                super();
    
                minWidth = 150;
    
                addChild(textField);
            }
    
            public function setLabelText(items:Array, labelField:String = "label"):void
            {
                var labelText:String;
    
                var numItems:int = items.length;
    
                if (numItems > 1)
                {
                    labelText = numItems.toString() + " items";
                }
                else
                {
                    var firstItem:Object = items[0];
    
                    labelText = firstItem[labelField];
                }
    
                textField.text = labelText;
            }
        }
    }
    

    【讨论】:

    • 谢谢,这是一个更好的方法。但是,我在使其正常工作时遇到了一些麻烦。我只是使用 2 个 CustomADG 并将一个分支拖到另一个分支,但是在 dropTagertItemRenderer == null 语句中它退出了。知道为什么 dropTargetItemRenderer 为空吗?
    • 我为 Tee 控制实现了这个。所有条件都有效,但是当我最终拖放时,该项目不会被拖放(合并)到目标。我已经设置了 dragMoveEnabled="true"
    【解决方案2】:

    如果对象是叶子,您可以尝试处理dragEnter() 事件以停止拖动。

    【讨论】:

    • 但那是在放置目标一侧..所以拖动已经开始。
    • 哎呀,我的错。我认为您需要使用 DragManager 并手动与之交互。查看“手动添加拖放”部分下的adobe.com/devnet/flex/quickstart/adding_drag_and_drop
    • 关于如何发送 dragInitiator 变量的任何线索?我试过: var source:DragSource = new DragSource(); source.addData(grid.selectedItem, "gridItem"); DragManager.doDrag(UIComponent(grid.indexToItemRenderer(grid.selectedIndex)), 源, 事件);没有运气。
    • var dragInitiator:AdvancedDataGrid = event.currentTarget as AdvancedDataGrid.
    • 可以抓取整个网格,但我只想抓取特定的列表项。
    猜你喜欢
    • 2011-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-08
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    相关资源
    最近更新 更多