2

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

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

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

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

2 回答 2

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;
        }
    }
}
于 2009-07-20T18:18:44.363 回答
0

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

于 2009-07-20T15:01:43.913 回答