Flex AdvancedDataGrid 树自定义拖动

发布于 2024-07-29 00:57:50 字数 445 浏览 4 评论 0原文

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

我在这方面遇到了很大的困难,尝试使用 MouseDown 事件,但运气不佳!

好吧,我想我已经可以通过鼠标按下来判断该项目是否是树叶的分支。 关于如何使用高级数据网格执行自定义拖动有任何帮助吗?

    var grid : AdvancedDataGrid = AdvancedDataGrid(event.currentTarget);
    if(grid.selectedItem.hasOwnProperty("categories") 
        && grid.selectedItem.categories!=null) { 
          Alert.show("yes"); 
    }
    else { Alert.show("no"); } 

I'd like to implement a custom drag on an AdvancedDataGrid tree structure, which only allows the drag on the branches (not leaves).

I'm having much difficultly with this, trying to use the MouseDown event, but not having luck!

Okay, I think I've got the mousedown able to figure out if the item is a branch of leaf. Any help on how to perform the custom drag with an advanceddatagrid??

    var grid : AdvancedDataGrid = AdvancedDataGrid(event.currentTarget);
    if(grid.selectedItem.hasOwnProperty("categories") 
        && grid.selectedItem.categories!=null) { 
          Alert.show("yes"); 
    }
    else { Alert.show("no"); } 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

染年凉城似染瑾 2024-08-05 00:57:50

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

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

CustomADG.as:DragProxyContainer.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.
        }
    }
}

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;
        }
    }
}

I've tried many different ways to do this, and this is the best solution that I have come up with. AdvancedDataGrid already has logic built in to handle the mouseMove/mouseOver/mouseDown events, so there's no need to recreate it. Simply override the DragEvent handlers.

I have duplicated the code I use in several applications that need similar functionality, included your logic for determining if the item can be dragged, as well as some logic to determine if it can be dropped in a certain location. I have also included extensive commenting to help explain why certain things are done. I hope this helps!

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;
        }
    }
}
顾铮苏瑾 2024-08-05 00:57:50

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

You can try handling the dragEnter() event to stop dragging if the object is a leaf.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文