The Flex3 Tree control is an easy to use way to display hierarchical data in a user friendly way. However, the tree control, like tree controls for other languages has some quirks. I will detail some of the quirks in coming weeks, but the quirk for today was particularly troubling to find.
When building a commercial entertainment application with 2 trees listing separate groups of data, we encountered strange behavior following drag-and-drop operations. In this application, users can drag files or folders from one tree to another in either direction. The tree control has built-in support for drag-and-drop operations, but this application had both custom drag event handlers and item renderers. Dragging an object from one tree to the other seemed to work well. Both trees contained the expected data, and the database was updated as expected. However, after completing the drop operation, when we moved the mouse anywhere on the application, the target tree would automatically scroll in response to the mouse movement. If an object was dragged back to the original tree, then that tree would exhibit the same auto scrolling behavior.
See the sample application below. If the nodes are expanded to the point of displaying the vertical scroll bar, and an object is dragged from one tree to another, the target tree will exhibit this unwanted scrolling behavior.
We searched the Internet, and no one else seemed to have this problem. There were some similar problems with datagrids, but if we were the only ones having this problem, there must be something wrong with our drag handlers. We tried everything. We made sure parent class event handlers were called, we tried forcing focus onto other objects, and we even tried turning scrolling off and back on. It was clear that something in the drag operations was not being cleared, closed or reset.
Eventually we found a bug report at Adobe. The report provided the answer to our problem. However, this report indicates that this is not a bug, rather it is caused by an incomplete implementation by the developer of a dragDrop handler override. Makes sense. We had a dragDrop handler override, but we were making sure that we were calling the Tree's default handler. In fact, the tree controls above are derived from the Tree control, but no handlers are overridden. The Tree's default handlers are responding to the dragDrop event.
The solution, nowhere in reference documentation that we could find and involving flash internals feels like more of a work around. However, the solution is relatively simple and effective.
First, get a reference to the mx internals.
import mx.core.mx_internal;
Next, in your dragDropHandler, clear lastDragEvent and reset drag scrolling.
override protected function dragDropHandler(event:DragEvent):void
{
event.target.mx_internal::lastDragEvent = null;
event.target.mx_internal::resetDragScrolling();
if (event.isDefaultPrevented())
return;
super.dragDropHandler(event);
}
In this override, we call super.dragDropHandler(event) to invoke the default behavior, but this call should not be needed to solve the scrolling problem. In the trees below, objects can be dragged from one tree to another, and the unwanted scrolling behavior is gone.
Next up, item renderer reuse. Flex will reuse them whether you're ready for it or not.
23cb577e-e6b8-48c4-82ff-6c195ef01972|1|5.0