项和一个树控件拖放
拖拽元素到Tree控件,和从Tree控件拖拽出元素创建一个应用程序,实现拖拽元素从Tree控件中,或到Tree控件是令人畏惧的,很明显,因为需要大量的事件处理逻辑。本节提供2个例子,来示范实现这2种功能的技术。从Tree控件中拖拽出元素下边的例子展示如何从Tree控件中拖拽元素到DataGrid控件中。Tree控件的数据提供器是XML对象。通过拖拽事件处理方法前的注释可以使你读懂整个应用程序。
例子
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.controls.Label;
import mx.controls.List;
import mx.collections.ArrayCollection;
import mx.core.DragSource;
import mx.controls.Tree;
import mx.controls.DataGrid;
import mx.controls.listClasses.ListBase;
import mx.events.DragEvent;
import mx.containers.Canvas;
import mx.managers.DragManager;
import mx.core.UIComponent;
[Bindable]
private var dataGridProvider:ArrayCollection = new ArrayCollection();
/**
* Handles the dragEnter event on the DataGrid control.
* If the dragInitiator is the Tree control, then only nodes of type "restaurant"
* are permitted to be dropped.
* Here you can see that by examining the dragSource you can determine if
* the control should accept the drop. The DataGrid control would not
* know how to treat a branch+children from the Tree control, so only leaf (restaurant)
* nodes are accepted.
*/
private function onDragEnter( event:DragEvent ) : void
{
if( event.dragInitiator is Tree ) {
var ds:DragSource = event.dragSource;
if( !ds.hasFormat("treeItems") ) return; // no useful data
var items:Array = ds.dataForFormat("treeItems") as Array;
for(var i:Number=0; i < items.length; i++) {
var item:XML = XML(items[i]);
if( item.@type != "restaurant" ) return; // not what we want
}
}
// If the Tree control passes or the dragInitiator is not a Tree control,
// accept the drop.
DragManager.acceptDragDrop(UIComponent(event.currentTarget));
}
/**
* Handles the dragOver event on the DataGrid control.
* If the dragInitiator is the Tree control, only copy is allowed. Otherwise, a move
* or link can take place from the List control.
*/
private function onDragOver( event:DragEvent ) : void
{
if( event.dragInitiator is Tree ) {
DragManager.showFeedback(DragManager.COPY);
} else {
if (event.ctrlKey)
DragManager.showFeedback(DragManager.COPY);
else if (event.shiftKey)
DragManager.showFeedback(DragManager.LINK);
else {
DragManager.showFeedback(DragManager.MOVE);
}
}
}
/**
* Handles the dragExit event on the drop target and just hides the
* the drop feedback.
*/
private function onDragExit( event:DragEvent ) : void
{
var dropTarget:ListBase=ListBase(event.currentTarget);
dropTarget.hideDropFeedback(event);
}
/**
* Handles the dragDrop event on the DataGrid when the
* drag proxy is released.
*/
private function onGridDragDrop( event:DragEvent ) : void
{
var ds:DragSource = event.dragSource;
var dropTarget:DataGrid = DataGrid(event.currentTarget);
var arr:Array;
if( ds.hasFormat("items") ) {
arr = ds.dataForFormat("items") as Array;
} else if( ds.hasFormat("treeItems") ) {
arr = ds.dataForFormat("treeItems") as Array;
}
for(var i:Number=0; i < arr.length; i++) {
var node:XML = XML(arr[i]);
var item:Object = new Object();
item.label = node.@label;
item.type = node.@type;
dataGridProvider.addItem(item);
}
onDragExit(event);
}
/**
* Intercepts the dragComplete event on the Tree control
* and prevents the default behavior from happening. This is necessary
* if the item being dragged from the Tree control is dropped on a non-Tree
* object, such as the DataGrid.
*/
private function onTreeDragComplete(event:DragEvent):void {
event.preventDefault();
}
/**
* Selects all of the items in the List if Ctrl+A is picked when the List control
* has focus.
*/
private function selectAllMaybe( event:KeyboardEvent ) : void
{
if( event.ctrlKey && event.keyCode == 65 ) {
var l:List = List(event.currentTarget);
var allItems:Array = new Array(l.dataProvider.length);
for(var i:Number=0; i < allItems.length; i++) {
allItems[i] = i;
}
l.selectedIndices = allItems;
}
}
]]>
</mx:Script>
<mx:XML id="treeData" xmlns="">
<root>
<node label="Massachusetts" type="state" data="MA">
<node label="Boston" type="city" >
<node label="Smoke House Grill" type="restaurant" />
<node label="Equator" type="restaurant" />
<node label="Aquataine" type="restaurant" />
<node label="Grill 23" type="restaurant" />
</node>
<node label="Provincetown" type="city" >
<node label="Lobster Pot" type="restaurant" />
<node label="The Mews" type="restaurant" />
</node>
</node>
<node label="California" type="state" data="CA">
<node label="San Francisco" type="city" >
<node label="Frog Lane" type="restaurant" />
</node>
</node>
</root>
</mx:XML>
<mx:Label x="34" y="40" text="Drag items from this Tree"/>
<mx:Label x="34" y="55" text="(items are copied)"/>
<mx:Tree x="34" y="81" width="181" height="189"
dataProvider="{treeData.node}"
labelField="@label"
dropEnabled="false"
dragEnabled="true"
dragComplete="onTreeDragComplete(event)"
dragMoveEnabled="false"
/>
<mx:Label x="291" y="55" text="Drop items from Tree here"/>
<mx:DataGrid x="291" y="81" height="189"
dragEnabled="true"
dataProvider="{dataGridProvider}"
dragEnter="onDragEnter(event)"
dragOver="onDragOver(event)"
dragDrop="onGridDragDrop(event)"
dragExit="onDragExit(event)">
<mx:columns>
<mx:DataGridColumn headerText="Label" dataField="label"/>
<mx:DataGridColumn headerText="Type" dataField="type"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>