1、,第11章 Flex 4组件间处理:拖放,11.1 拖放行为概述,11.2 在列表类组件中使用拖放,11.3 对非列表类组件使用拖放,11.1 拖放行为概述,11.1.1 拖放过程 1初始化 用户通过使用鼠标选中一个Flex组件,或组件中的某一个选项,按住鼠标移动组件或选项移动,发起一个拖放操作。 2拖动 当按住鼠标按键,用户在Flex应用程序中移动鼠标,Flex显示一个表示正在拖放的图片,这个图片代表拖放对象,称为“拖动代理”(Drag proxy)。 3放下 当一个用户移动“拖动代理”划过一个Flex组件的时候,这个组件有可能变成“放下目标”(Drop target)。,11.1.2 拖放
2、事件,Flex中的拖放操作涉及的类主要有以下几个。 (1)DragManager:管理拖放操作。 (2)DragSource:确定并且储存那些被拖放的数据。 (3)DragEvent:响应拖放事件。 Flex中的拖放操作涉及的事件主要有以下几种。 (1)mouseDown和mouseMove。 mouseDown事件在用户通过按住鼠标键选择一个组件时派发。 标移动时派发。 (2)dragEnter。 当一个拖放代理从目标组件外移动到目标组件上时派发。一个组件成为一个放下目标时必须为这个事件定义一个监听器。 (3)dragDrop。 当鼠标在目标上释放时派发。 (4)dragOver和dragE
3、xit。 dragOver事件当用户在目标组件上移动鼠标时派发;dragExit事件当用户拖动代理移出目标组件,并且没有放置数据时派发。 (5)dragComplete。 在一个拖放操作完成时派发。,11.1.3 支持拖放的组件,用户只要定义组件中的一些属性,就可以实现拖放操作。涉及如下几个属性。 (1)dragEnabled (2)dragMoveEnabled (3)dropEnabled,11.1.3 支持拖放的组件,对于非列表类组件或dragEnabled属性值设为false的列表类组件,需要人为控制拖动和放下事件,实现的原理如下所示。 (1)对于没有dragEnabled属性的组件,
4、必须使组件能够接收到用户已经开始启动一个拖放操作,然后使其明确成为一个拖动初始者。 (2)当鼠标处于按下状态时,用户可以拖动鼠标,Flex则显示移动的拖动代理图像。 (3)如果用户将拖放代理移动到一个Flex组件上,则Flex派发一个dragEnter事件到这个准放下目标。 (4)dragEnter事件监听器将检查DragSource对象,以便决定拖放数据是否是可接受的格式。 (5)如果放下目标拒绝放下,放下目标组件的父级链中组件将逐一被检查,从而检测是否有可以接受释放数据的组件。 (6)如果放下目标或者其父组件中的一个组件可以接受放下,当用户在目标上移动代理时,Flex派发一个dragOve
5、r事件。 (7)如果用户放弃在放下目标上放下数据,并且一直没有松开鼠标同时将拖放代理移动到释放目标之外,则Flex派发一个dragExit事件,放下目标可以处理这个事件。 (8)如果用户在放下目标上松开鼠标,则Flex派发一个dragDrop事件,然后放下目标的dragDrop事件监听器添加拖放数据到目标中。 (9)如果拖放操作完成,则Flex派发一个dragComplete事件,拖放初始者可以处理这个事件。,11.2 在列表类组件中使用拖放,11.2.1 基本拖放 在panel容器中定义两个List组件sl和dl,sl作为拖放初始者,dl则作为放下目标。将sl的dragEnabled和dra
6、gMoveEnabled属性值都设为true,表示运行拖出和移动数据,将dl的dropEnabled属性值设为true,表示允许放下数据。代码如下:,11.2.1 基本拖放,初始化sl和dl中的数据源,代码如下:,11.2.1 基本拖放,程序执行后显示初始状态如图11.1所示。从第一个列表中选中一个选项并按住鼠标拖动,效果如图11.2所示。拖动到另一个列表后的效果如图11.3所示。,11.2.2 双向拖放,如果将两个列表类组件的dragEnabled、dragMoveEnabled和dropEnabled属性值都设为true,则可以实现双向拖放行为。 例如,在数据表格组件中实现双向拖放行为的示
7、例代码所示。 程序执行后,选中“列表1”中的几行数据拖动到“列表2”,再从“列表2”中拖动数据到“列表1”中,如图所示。,11.3 对非列表类组件使用拖放,11.3.1 实现拖放 1新建组件 新建Panel容器和Button组件,Button组件的位置设于Panel容器外,代码如下:在移动Button组件时派发mouseMove事件,调用dragSource()函数初始化拖放操作。,11.3.1 实现拖放,2拖放初始化 在定义触发的事件处理函数前引入要使用的类,代码如下: import mx.events.DragEvent; import mx.core.DragSource; import
8、 mx.managers.DragManager; import flash.events.MouseEvent; 定义实现初始化拖放操作的dragSource()函数,代码如下: private function dragSource(e:MouseEvent):void /CurrentTarget指定要实现拖放的初始化目标var dragInitiator:Button=Button(e.currentTarget);var dragSource: DragSource=new DragSource();/向对象添加拖放数据dragSource.addData(“x“ : e.local
9、X, “y“ : e.localY,“button“);DragManager.doDrag(dragInitiator, dragSource, e); ,11.3.1 实现拖放,3拖放到目标上 当Button组件拖动到Panel容器上,鼠标未释放时调用onEnter()函数,代码如下所示: private function onEnter(e:DragEvent): void /如果标号为已经设定的标号“button”则接受拖来的物体if(e.dragSource.hasFormat(“button“) DragManager.acceptDragDrop(Panel(e.target)
10、); DragSource对象的hasFormat()方法检测数据对象中是否包含所请求的格式,如果有则返回true,否则返回false,参数为指定数据格式的标签。,11.3.1 实现拖放,4放下数据 当目标接受拖动对象,并且用户在面板容器上放下鼠标时触发dragDrop事件,调用onDrop()函数,代码如下所示: private function onDrop(e:DragEvent):void var myData:Object = new Object();myData = e.dragSource.dataForFormat(“button“); btn.x = this.mouseX
11、 - myData.x;btn.y = this.mouseY - myData.y; 在onDrop()函数中设置Button组件中心的位置为鼠标所在的位置,则Button组件从Panel容器外移动到了Panel容器中。,11.3.1 实现拖放,程序完整代码所示。 程序执行结果如图所示。,11.3.2 设置拖放代理,拖动代理是在拖动组件时显示的图像,可以在mouseDown和mouseMove事件处理函数内,DragManger类的doDrag()方法中自定义拖动代理。 例如,要对前面11.3.1节中拖动的Button组件设置一个拖动代理,只需要修改dragEnter事件触发的dragSou
12、rce()函数,并在该函数中定义一个拖动图像,代码所示。 在定义图像对象前需要引入图像类,代码如下; import mx.controls.Image; 程序的执行结果如图所示。,11.3.3 处理放置与退出,当用户拖动组件到放下目标上并移动鼠标时将触发dragOver事件,可以忽略这个事件,也可以用这个事件为用户提供反馈。 参数feedback设置拖放操作的反馈指示符,该参数有如下几种可能的值。 DragManager.COPY DragManager.MOVE DragManager.LINK DragManager.NONE 示例代码所示。,11.3.3 处理放置与退出,程序执行后,拖动第一个列表中的选项到第二个列表中,目标列表的边框会变为红色,数据放置到目标列表后边框又恢复原样,如图所示。,