可视化的开发环境就是要允许用户能够在屏幕中通过鼠标选择或者移动程序中的各种物件。拖放就允许用户选择一个物件,比如List控件或者Flex中的Image控件,然后把它拖到另外一个组件(容器),再把这个物件添加到这个组件(容器)中。
你可以添加对所有Flex组件拖放的支持,当然,Flex也本身包含了对拖放的built-in的支持和操作,比如List, Tree 和DataGrid控件,这些空间都能自动处理拖放所需要的操作。
拖放的操作包行三个主要的过程:初始化、拖以及放过程。
² 初始化:用户通过按下鼠标选择或者移动一个Flex组件,或者Flex组件中的一项来完成初始化动作。
² 拖:当用户仍然按住鼠标不放的时候,他可以在Flex程序中移动鼠标,拖的过程中所显示一个image就叫着一个drag proxy.它包含了被拖组件(drag source)的数据。
² 放:当用户把drag proxy移动到另外一个组件(容器),这个组件(容器)就成为了一个drop target.这个drop target就会检查drag source物件来判断里头的数据类型或者格式是否恩那个被drag target所接受。如果可以接受,即两种数据类型或者格式符合,就会允许用户放下所拖的组件。否则,则不允许用户放下组件。
拖和放都是事件驱动的。要配置一个组件作为drag initiator或者 drag target,你必须为特定的事件书写事件处理,比如dragDrop或者dragEnter事件。
一些经常被拖放的组件,Flex提供了Built-in事件处理来自动执行拖放操作。这些控件都是ListBase这个类的子类,可被认作为list-based控件。
对于移动操作,即你从drag initiator移动一个数据组件到drag target, list-based控件可以处理所有的拖放的时间处理。但是你如果要拷贝一个拖放组件数据到drop target,那么你就必须书写事件处理无论是list-based控件还是nonlist-based控件。
list-based控件
以下的控件都包行了对拖放的bulit-in的支持。
ü DataGrid
ü HorizontalList
ü List
ü PrintDataGrid
ü TileList
ü Tree
这些控件的built-in支持可以让用户从一个支持drag-enabled的控件把items移动到另外一个支持drop-enabled控件中。然而,要拷贝items,用户需要书写额外的逻辑操作。比如:以下的程序允许用户把List控件中的item移动到其他的控件中:
xmlns:mx=""
creationComplete="initApp();">
import mx.collections.ArrayCollection;
private function initApp():void {
srclist.dataProvider =
new ArrayCollection(['Reading', 'Television', 'Movies']);
destlist.dataProvider = new ArrayCollection([]);
}
]]>
text="Available Activities"/>
id="srclist"
allowMultipleSelection="true"
dragEnabled="true"
dragMoveEnabled="true"/>
text="Activities I Like"/>
id="destlist"
dropEnabled="true"/>
id="b1"
label="Reset"
click="initApp()"
/>
通过设置第一个list的dragEnabled属性为true,以及第二个list中的dropEnabled属性为true,用户就可以从第一个list拖放item到第二个list,而不需要去担心底层是怎么执行的。
对于所有list类的控件除了Tree控件,dragMoveEnabled属性的值为false,所以你只能从一个控件拷贝元素到另外一个控件。通过设置第一个list中的dragMoveEnabled值为ture 你就可以移动或者拷贝数据了。对于Tree 控件,dragMoveEnabled的默认是为true的。
当dragMoveEnabled的值为ture的时候,拖放的默认执行操作是移动数据,如果要执行拷贝操作,在移动的过程中,通过按下Control 这个键就可以完成拷贝的操作。
在执行拖放的操作过程中,唯一的要求就是数据(data provider)的结构必须与两个控件要求的结构相符。否则将不能正确显示拖放的数据内容。
你可以更改托拖放的数据类型使得他们完成兼容的操作。以下的例子通过设置两个list-baed控件的dragEnabled,dropEnabled,和drogMoveEnabled属性值为ture来运行双向的拖放动作。
xmlns:mx=""
creationComplete="initApp();">
import mx.collections.ArrayCollection;
private function initApp():void {
srcgrid.dataProvider = new ArrayCollection([
{Artist:'Carole King', Album:'Tapestry', Price:11.99},
{Artist:'Paul Simon', Album:'Graceland', Price:10.99},
{Artist:'Original Cast', Album:'Camelot', Price:12.99},
{Artist:'The Beatles', Album:'The White Album', Price:11.99}
]);
destgrid.dataProvider = new ArrayCollection([]);
}
]]>
text="Available Albums"/>
id="srcgrid"
allowMultipleSelection="true"
dragEnabled="true"
dropEnabled="true"
dragMoveEnabled="true">
dataField="Artist"/>
dataField="Album"/>
dataField="Price"/>
text="Buy These Albums"/>
id="destgrid"
allowMultipleSelection="true"
dragEnabled="true"
dropEnabled="true"
dragMoveEnabled="true">
dataField="Artist"/>
dataField="Album"/>
dataField="Price"/>
id="b1"
label="Reset"
click="initApp()"
/>
在同个控件中执行拖放操作一般是用来list-based控件中的item重组。下个例子当中,定义个Tree控件,允许用户通过拖放重组里面的节点。这个例子当中,你只需设置dragEnabled和dropEnabled两个属性为trure,因为Tree控件中的dragMoveEnabled的属性默认值为true.
xmlns:mx="">
// Initialize the data provider for the Tree.
private function initApp():void {
firstList.dataProvider = treeDP;
}
]]>
id="treeDP">
id="firstList"
showRoot="false"
labelField="@label"
dragEnabled="true"
dropEnabled="true"
allowMultipleSelection="true"
creationComplete="initApp();"/>
当然,list-based控件的拖放动作拥有很多属性值,具体可以参考development guide.这不多介绍了。