Use List Base controls in Item Renderers and doing drag/drop operations

I am working on a project where i use a custom item renderer. This renderer is a VBox that contains a label and a List control.

The List control has a built in support for drag and drop. All went fine for me and i was able to drag and drop items from one list to the other (dragging from a list in itemRenderer A to a list in itemRenderer B)

The problem stared when i dragged item from a list that was located in an iemRenderer at the top to a list that was located in itemRenderer that was "far" below so scrolling had to be done.

In that case, after scrolling down, and dropping the item where i wanted, the items would disappear. This was very strange to me and i could not figure it at start.

Later i recalled that Flex re-uses item renderers. this means that the same itemRenderer can serve more then one line from the dataProvider.

This is exactly what happens when the user scrolls the view. The same itemRenderers get filled with new Data.

So why is this a problem for dragging and dropping?

The default implementation in ListBase is like that:


protected function addDragData(ds:Object):void // actually a DragSource
{
ds.addHandler(copySelectedItems, "items");
}

This means that the actual dragged items are not added / kept correctly. Instead the dragged items are filled later by calling "copySelectedItems" function.

So , now we see the problem , since the ItemRenderer that used to hold the List control was re-used. A new "Fresh" data was inserted/injected to it. When having a new DataProvider, the list of selected items get cleared and this is the reason that the list of items was empty during Drop and the drop was not executed.

So how do we solve it?
We create a new class that inherits from List and we override the addDragData function. See below


package com.softologia.itemRendererEnabledList
{
import mx.collections.ArrayCollection;
import mx.controls.List;
import mx.events.DragEvent;
import mx.managers.DragManager;

public class ItemRendererList extends List
{
public function ItemRendererList()
{
super();
}

protected override function addDragData(ds:Object):void // actually a DragSource
{
ds.addData(selectedItems, "items");
}
}
}

See full source code here
http://www.softologia.com/sites/default/files/itemRendererEnabledList.rar

See Demo of the problem and solution here
http://www.softologia.com/sites/default/files/itemRendererEnabledList.swf