Flex中有一些控件内置了对drag-and-drop操作的支持,实现也相对方便,但往往要完成这样的操作,将一幅图片(没有内置drag-and-drop操作)拖动到一个表格中,在表格中显示相关信息,该如何实现呢?答案很简单,你必须显式的通过一系列专门的类和事件来添加对drag-and-drop的支持。
以下是实现drag-and-drop操作所用到的类和事件,
drag-and-drop 类:
drag-and-drop 事件:
drag-and-drop 过程:
- 一个组件通过以下方法中的一种成为一个 drag-and-drop 初始器:
拥有 dragEnabled 属性的组件(这些组件包括 List,Tree,DataGrid,PrintDataGrid Menu,HorizontalList 以及 TileList):如果 dragEnabled 属性设置为 true,当用户此组件点击移动鼠标时,Flex 自动将其转为初始器。
没有 dragEnabled 属性的组件:对于其他所有的组件,必须接收到用户启动一个拖拽操作的趋 势,然后显式的成为一个初始器。代表性地,你使用 mouseMove 或者 mouseDown 事件来启动 drag-and-drop 操作。
- 组件创建一个 mx.core.DragSource 类的实例,其中包含要拖拽的数据,并且指定数据的格式。
- 组件调用 mx.managers.DragManager.doDrag() 方法,来初始化 drag-and-drop 操作。
- 当鼠标键一直按住时,用户在程序内部移动鼠标。Flex 在程序中显示拖拽代理图像。
- 如果用户移动拖拽代理到一个 Flex 组件之上,Flex 广播一个 dragEnter 事件到这个准释放目标。这个目标组件必须为 dragEnter 事件定义一个事件侦听器,这样才能成为一个释放目标。
dragEnter 事件侦听器将检查 DragSource 对象以便决定拖拽数据是否是可接受的格式。为了接受释放,事件侦听器调用 DragManager.acceptDragDrop() 方法
-
- 如果释放目标拒绝释放,释放目标组件的父级链中组件将逐一被检查,来检测是否有可以接受释放数据的组件。
- 如果释放目标或者其父组件中的一个组件可以接受释放,当用户在目标上移动代理时,Flex 广播一个 dragOver 事件。
- 可选地,目标对象可以对 dragOver 事件进行处理。例如,目标可以使用这个事件侦听器来使其自身获得焦点。
- 如果用户放弃在释放目标上释放数据,并且一直没有松开鼠标将拖拽代理移动到释放目标之外,Flex 广播一个 dragExit 事件。释放目标可以处理这个事件,例如去回滚任何在 dragOver 事件侦听器中进行的操作。
- 如故用户在释放目标上松开鼠标,Flex 广播一个 dragDrop 事件。释放目标的 dragDrop 事件侦听器添加拖拽数据到目标中。
- 如果拖拽操作完成,Flex 广播一个 dragComplete 事件。拖拽初始器可以处理这个事件,例如删除从数据提供器(data provider)中删除拖拽数据。
实例描述:
控件A拖动到控件 B上,然后改变各自的位置。
1.ControlA.mxml
1 <?xml version="1.0" encoding="utf-8"?>
2
<
mx:Canvas backgroundColor
=
"
#000000
"
mouseDown
=
"
startMove(event)
"
mouseUp
=
"
stopMove(event)
"
xmlns:mx
=
"
http://www.adobe.com/2006/mxml
"
width
=
"
400
"
height
=
"
300
"
>
3 < mx:Script >
4 <! [CDATA[
5 import mx.core.DragSource;
6 import mx.managers.DragManager;
7 /* ***************************************************************************
8 * 控件A
9 * 用于拖动,捕获mouseDown 和 mouseUp事件,触发拖动
10 *************************************************************************** */
11
12 /* *
13 * 鼠标按下事件处理方法
14 */
15 private function startMove(event:Event): void
16 {
17 // Sprite 类的startDrag方法来触发拖动
18 Sprite(event.target).startDrag();
19
20 // 其他控件感知拖动事件,需要用DragManager的doDrag 方法触发
21 var obj:DragSource = new DragSource();
22 // Data 包含,拖动时该控件的x,y 信息
23 var location:String = this .x + " , " + this .y;
24 obj.addData(location, " LocationFormat " );
25 var mouseEvent:MouseEvent = new MouseEvent(MouseEvent.MOUSE_DOWN);
26 DragManager.doDrag( this ,obj,mouseEvent);
27 }
28 /* *
29 * 鼠标弹起事件处理方法
30 */
31 private function stopMove(event:Event): void
32 {
33 // Sprite 类的stopDrag 方法来触发停止拖动
34 Sprite(event.target).stopDrag();
35 }
36
37
38 ]] >
39 < / mx:Script>
40 < mx:Button x = " 48.5 " y = " 38 " label = " A " width = " 161 " height = " 89 " fontSize = " 28 "/ >
41
42 < / mx:Canvas>
43
3 < mx:Script >
4 <! [CDATA[
5 import mx.core.DragSource;
6 import mx.managers.DragManager;
7 /* ***************************************************************************
8 * 控件A
9 * 用于拖动,捕获mouseDown 和 mouseUp事件,触发拖动
10 *************************************************************************** */
11
12 /* *
13 * 鼠标按下事件处理方法
14 */
15 private function startMove(event:Event): void
16 {
17 // Sprite 类的startDrag方法来触发拖动
18 Sprite(event.target).startDrag();
19
20 // 其他控件感知拖动事件,需要用DragManager的doDrag 方法触发
21 var obj:DragSource = new DragSource();
22 // Data 包含,拖动时该控件的x,y 信息
23 var location:String = this .x + " , " + this .y;
24 obj.addData(location, " LocationFormat " );
25 var mouseEvent:MouseEvent = new MouseEvent(MouseEvent.MOUSE_DOWN);
26 DragManager.doDrag( this ,obj,mouseEvent);
27 }
28 /* *
29 * 鼠标弹起事件处理方法
30 */
31 private function stopMove(event:Event): void
32 {
33 // Sprite 类的stopDrag 方法来触发停止拖动
34 Sprite(event.target).stopDrag();
35 }
36
37
38 ]] >
39 < / mx:Script>
40 < mx:Button x = " 48.5 " y = " 38 " label = " A " width = " 161 " height = " 89 " fontSize = " 28 "/ >
41
42 < / mx:Canvas>
43
1 <?xml version="1.0" encoding="utf-8"?>
2
<
mx:Canvas backgroundColor
=
"
#000000
"
dragOver
=
"
dragOverHandler(event)
"
dragDrop
=
"
doDragDropHandler(event)
"
dragEnter
=
"
doDragEnterHandler(event)
"
xmlns:mx
=
"
http://www.adobe.com/2006/mxml
"
width
=
"
400
"
height
=
"
300
"
>
3 < mx:Script >
4 <! [CDATA[
5 import mx.core.UIComponent;
6 import mx.managers.DragManager;
7 import mx.events.DragEvent;
8 /* ***************************************************************************
9 * 控件B
10 * 处理dragOver,dragDrop,dragEnter事件
11 *************************************************************************** */
12 /* *
13 * dragOver 事件处理
14 */
15 public function dragOverHandler(event:DragEvent): void
16 {
17 if (event.ctrlKey)
18 DragManager.showFeedback(DragManager.COPY);
19 else if (event.shiftKey)
20 DragManager.showFeedback(DragManager.LINK);
21 else
22 DragManager.showFeedback(DragManager.MOVE);
23 }
24
25 /* *
26 * dragEnter 事件,主要是,要接收一些拖动到其上的控件,特定的控件,不然所有的控件都可以拖动到其上。
27 */
28 public function doDragEnterHandler(event:DragEvent): void
29 {
30 var dropTarget:UIComponent = event.currentTarget as UIComponent;
31 if (event.dragSource.hasFormat( ' LocationFormat ' ))
32 {
33 DragManager.acceptDragDrop(dropTarget);
34 }
35 }
36
37 /* *
38 * 在此处得知拖动过来的控件,以及一些信息
39 */
40 public function doDragDropHandler(event:DragEvent): void
41 {
42 var dragObj:String = event.dragSource.dataForFormat( " LocationFormat " ).toString();
43 var locationArray:Array = dragObj.split( " , " );
44 var x:Number = Number(locationArray[ 0 ]);
45 var y:Number = Number(locationArray[ 1 ]);
46 this .x = x;
47 this .y = y;
48 event.preventDefault();
49
50 }
51 ]] >
52 < / mx:Script>
53 < mx:Button x = " 35.5 " y = " 36 " label = " B " width = " 161 " height = " 89 " fontSize = " 28 "/ >
54
55 < / mx:Canvas>
56
3 < mx:Script >
4 <! [CDATA[
5 import mx.core.UIComponent;
6 import mx.managers.DragManager;
7 import mx.events.DragEvent;
8 /* ***************************************************************************
9 * 控件B
10 * 处理dragOver,dragDrop,dragEnter事件
11 *************************************************************************** */
12 /* *
13 * dragOver 事件处理
14 */
15 public function dragOverHandler(event:DragEvent): void
16 {
17 if (event.ctrlKey)
18 DragManager.showFeedback(DragManager.COPY);
19 else if (event.shiftKey)
20 DragManager.showFeedback(DragManager.LINK);
21 else
22 DragManager.showFeedback(DragManager.MOVE);
23 }
24
25 /* *
26 * dragEnter 事件,主要是,要接收一些拖动到其上的控件,特定的控件,不然所有的控件都可以拖动到其上。
27 */
28 public function doDragEnterHandler(event:DragEvent): void
29 {
30 var dropTarget:UIComponent = event.currentTarget as UIComponent;
31 if (event.dragSource.hasFormat( ' LocationFormat ' ))
32 {
33 DragManager.acceptDragDrop(dropTarget);
34 }
35 }
36
37 /* *
38 * 在此处得知拖动过来的控件,以及一些信息
39 */
40 public function doDragDropHandler(event:DragEvent): void
41 {
42 var dragObj:String = event.dragSource.dataForFormat( " LocationFormat " ).toString();
43 var locationArray:Array = dragObj.split( " , " );
44 var x:Number = Number(locationArray[ 0 ]);
45 var y:Number = Number(locationArray[ 1 ]);
46 this .x = x;
47 this .y = y;
48 event.preventDefault();
49
50 }
51 ]] >
52 < / mx:Script>
53 < mx:Button x = " 35.5 " y = " 36 " label = " B " width = " 161 " height = " 89 " fontSize = " 28 "/ >
54
55 < / mx:Canvas>
56
3.主界面:TestDragOver.mxml
1 <?xml version="1.0" encoding="utf-8"?>
2
<
mx:WindowedApplication xmlns:mx
=
"
http://www.adobe.com/2006/mxml
"
layout
=
"
absolute
"
xmlns:local
=
"
*
"
>
3 < local:ControlA width = " 250 " height = " 250 " x = " 39 " y = " 10 " >
4
5 < / local:ControlA>
6 < local:ControlB x = " 344 " y = " 10 " width = " 250 " height = " 250 " >
7
8 < / local:ControlB>
9 < / mx:WindowedApplication>
10
3 < local:ControlA width = " 250 " height = " 250 " x = " 39 " y = " 10 " >
4
5 < / local:ControlA>
6 < local:ControlB x = " 344 " y = " 10 " width = " 250 " height = " 250 " >
7
8 < / local:ControlB>
9 < / mx:WindowedApplication>
10