views:

995

answers:

2

Hello,

I have another drag-and-drop question. I'm using DnD on a Tree component and it works fine, when I have up to 50-80 items in the tree. However, when I have 100-300 items, the simple drag-and-drop operation suddenly eats all my CPU capacity and the application freezes for up to 1 minute.

I suppose that happens because Flex is trying to redraw the proxy dragImage and, thus, needs to redraw all the 300 nodes. Is there a way to turn off the dragImage? A simple cursor arrow with a small rectangle will be enough for my purposes.

Has anybody else encountered this performance issue with Flex Tree component?

Thanks.

+1  A: 

I have worked with drag-and-drop with several of the List-based components in Flex, but have not experienced any issues with CPU capacity overload or application freezes. I would suggest running a profile in Flex Builder to see what's using up all that CPU and/or memory, and working to resolve that.

As for drag-and-drop, I've always leaned towards creating my own drag-and-drop functionality, so that I can do what I want with the data, and create my own proxy image. Here's how I start the drag in a Tree component:

override protected function mouseDownHandler(event:MouseEvent):void
{
    var eventPoint:Point = new Point(event.localX, event.localY);

    var eventPointGlobal:Point = super.localToGlobal(eventPoint);

    mouseDownPoint = super.globalToLocal(eventPointGlobal);

    super.mouseDownHandler(event);
}

// MouseMove Handler for manually initiating Drag functionality
override protected function mouseMoveHandler(event:MouseEvent):void
{
    super.mouseMoveHandler(event);

    if (!event.buttonDown || DragManager.isDragging)
        return;

    /* Create a point relative to this component from the mouse 
        cursor location. */
    var eventPoint:Point = new Point(event.stageX, event.stageY);

    var dragPoint:Point = super.globalToLocal(eventPoint);

    if (!mouseDownPoint)
        return;

    if (Math.abs(mouseDownPoint.x - dragPoint.x) <= 4 
            || Math.abs(mouseDownPoint.y - dragPoint.y) <= 4)
        return;

    if (!event.target is UITextField)
        return;

    if (selectedItems.length == 0)
        return;

    var dragSource:DragSource = new DragSource();

    var dragProxy:DragProxyContainer = new DragProxyContainer(); // This is my custom Drag Proxy Image that I reuse throughout my application (see below)

    dragProxy.setLabelText([selectedItem]);

    // Initiate the Drag Event
    DragManager.doDrag(this, dragSource, event, dragProxy, 
        -dragPoint.x+event.localX, -dragPoint.y+event.localY, 0.8);
}


package view
{
    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;
        }
    }
}
Eric Belair
A: 

i have found solution for the problem, see http://compile4fun.wordpress.com/2010/10/29/optimization-drag-and-drop / its in russian, but you can use google translate.

kemsky