DataGrid Drag Image
One of the great features in Flex is the ability to enable drag and drop from data grids with one simple statement, dragEnabled="true". Flick the switch and away you go dragging rows here and there. But what happens when you do not want to see the entire row being dragged around. What if you want to display something more meaniful and less bulky than the entire visible row. Well if you are using the mx.controls.DataGrid you are stuck, however there is a solution. Extend the DataGrid. Here is a working sample, once it is loaded do a right click to view the source code.
By default the DataGrid's dragImage property is protected and set to 'mx.controls.dataGridClasses.DataGridDragProxy'. To enable setting a custom dragImage on the DataGrid you can simply extend it to allow the use of a use defined drag image class.
<mx:DataGrid xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.dataGridClasses.DataGridDragProxy;
import mx.core.IUIComponent;
/**
* @public
* class to use as DragProxy image
* set the default value to the standard DataGridDragProxy class
*/
[Bindable]
public var dragProxyImage: Class = DataGridDragProxy;
override protected function get dragImage():IUIComponent
{
var image:IUIComponent = new dragProxyImage();
image.owner = this;
return image;
}
]]>
</mx:Script>
</mx:DataGrid>
Now that the DataGrid has been extended to allow a custom drag image, let's see how to use it. The first thing to do is to create a class to use as the drag image. It's a good idea to look over the source code for the mx.controls.dataGridClasses.DataGridDragProxy class as you will be able to see how to create a DragProxy that can work with one or multiple selected rows. Next, drop the new DataGrid into your mxml file, set the dragProxyImage value and you are done.
<controls:DataGrid
dataProvider="{dataSource}"
rowHeight="40"
dragEnabled="true"
height="140"
dragProxyImage="com.dgrigg.controls.CustomDragProxy"
allowMultipleSelection="true">
<controls:columns>
<mx:DataGridColumn headerText="Image" dataField="image">
<mx:itemRenderer>
<mx:Component>
<mx:Image source="{data.image}"/>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
<mx:DataGridColumn headerText="Product" dataField="name"/>
<mx:DataGridColumn headerText="Description" dataField="description"/>
</controls:columns>
</controls:DataGrid>
This same solution will work with the mx.controls.List. Click here to view a working sample. Once it is loaded do a right click to view the source code.
Dec 05, 2006 at 2:00 PM
I tried this method but had lots of trouble controling where the drag image was drawing itself. I wanted it directly under the mouse, but depending how you select your items and finally start the dragging, it wasn't always there. I'm guessing it might be because my data grid is wrapped in a canvas buried within many other levels of components.
I ended up just following the examples in the docs for adding drag and drop manually (not using dropEnabled/dragEnabled) in which you can specify a custom drag image class to use. This ended up working out much better for my needs.
Jason
Dec 05, 2006 at 5:06 PM
Hi Jason, I would recommend you read over the code in the 'mx.controls.dataGridClasses.DataGridDragProxy' class. You will find in there a more robust method for handling the proxy's x/y coordinates, relative to the row's position in the datagrid. My example was just a very simplistic one. I have other working versions that use the method in the DataGridDragProxy class and others that use the mouseX and mouseY properties with a localToGlobal call to position the proxy at the mouse pointer, and they work perfectly. It all depends on what you need, but there are a few very easy ways to get the proxy positioned where you need it. If you are trying to do multiple selected rows with the manual DragManager you will quickly discover a pile of problems, which is why I would recommend using the method I have come up with.
Dec 06, 2006 at 8:14 AM
Actually, I just ran across some issues with my method today. By using the moveMouse event of the datagrid to initiate the DragManager, it triggers when I move the scroll bars or any time I move the mouse over the datagrid with my mouse button down. This will confuse the users, so I wil look into your method again. I did try messing with localToGlobal to try getting the positioning the way I wanted it, but nothing I tried seemed to worked. I got the x position to follow the mouse propery, bt the y wasn't consistant depending on how I was selecting multiple rows and which I finally initiating the drag action with. I'll try again though... thanks for the feedback.
Apr 12, 2007 at 11:53 AM
Can you point me to mouseover with ajax in datagrid sample code?
Specifically, image to flv, mov, asx etc...
Thanks,
David Larew
Oct 12, 2007 at 8:40 AM
Amazing work Derrick!
Just one question, is there any way to get the DragImageProxy to port over to an embedded Image as a class?
When i drag the dg row, i just want to show one icon, represnting the column, its an embeded png as a class, and i cant get it to work for the life of me..
Thanks!
Jul 08, 2008 at 10:56 AM
Hi,
I am able to drag image/component from the DataGrid column, but I want to drag the component from first column and drop it into the second column. My component is a rectangular canvas and I want to drag and drop it into the second column where it should align itself based on the space and the second column canvas should accept the color of the of the canvas being dragged from first column.
Any kind of suggestions?
Thanks in advance,
C. M