如何阻止拖动List或DataGrid的某些项?
假设我有一个包含两个项目的列表:'Tom'和'Jerry'。只有'汤姆'应该是可拖动的,而不是'杰里'。
理想情况下,我有一个'isDragEnabled(item:Object):Boolean'函数,由拖动源查询。
我的困难始于'dragStart'事件处理程序对dragSource有一个空值这一事实,所以从一开始我就很难找到拖动开始的内容。
提前致谢!
PS有关于防止或取消跌落的一些讨论,但我没有看到很多关于防止阻力开始,因此这个问题。答案 0 :(得分:3)
如果你想要的是避免拖动项目,你应该使用这样的东西:
<fx:Script>
<![CDATA[
private function onDragStart(event:DragEvent):void {
var selectedNode:Object = itemsList.selectedItem;
if (selectedNode is not a draggable item) {
event.stopImmediatePropagation();
}
}
]]>
</fx:Script>
<s:List id="itemsList" dragStart="onDragStart(event)"/>
在拖动开始时立即调度DragStart事件,因此如果停止传播事件,则可以避免拖动项目。
答案 1 :(得分:2)
你可以做两件事:
您可以根据selectedItem的数据对象上的属性禁用列表中不可拖动的项目。这将导致它们在视觉上被禁用,您可能不需要,因此您也可以尝试...
您可以在选择有效项目(基于selectedItem的数据对象)时将列表的dragEnabled属性设置为“true”,并在项目无效时将其设置为“false”。
答案 2 :(得分:1)
好的,得到它,感谢Robusto,你的小费#2是灵感,但是我不得不使用一个鼠标聆听者 - 选择事件发生得太晚了。
在下面的示例中,我使用的是我some other question的代码。
此示例允许您仅拖动List或DataGrid中的第一项:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal" minWidth="955" minHeight="600">
<mx:List id="list" dataProvider="{['Tom','Jerry', 'Amy', 'Betty', 'Chris', 'Dean', 'Email', 'Floyd', 'Grant', 'Helen', 'Iris', 'Jack']}" minWidth="200"
mouseDown="onMouseDown(event)"
/>
<mx:DataGrid id="dg" dataProvider="{[{title:'Tom'},{title:'Jerry'}]}" minWidth="200"
mouseDown="onMouseDown(event)"
>
<mx:columns>
<mx:DataGridColumn dataField="title" />
</mx:columns>
</mx:DataGrid>
<mx:Script>
<![CDATA[
import mx.controls.listClasses.ListBase;
import mx.events.DragEvent;
protected function onMouseDown(event:MouseEvent):void
{
var listBaseComp:ListBase = ListBase(event.currentTarget);
var clickIndex:int = this.findClickedItemIndex(event.stageX, event.stageY, listBaseComp);
listBaseComp.dragEnabled = clickIndex == 0;
}
/**
* Returns a dataProvider item that displays at the given coords for the given dataGrid.
* Code provided by Stackoverflow user https://stackoverflow.com/users/165297/amarghosh,
* thanks a lot!
*/
protected function findClickedItemIndex(globalX:Number, globalY:Number, listComp:ListBase):int
{
var p1 : Point;
var p2 : Point;
var renderer : DisplayObject;
for(var i:int=0; i<listComp.dataProvider.length; i++) {
renderer = DisplayObject(listComp.indexToItemRenderer(i));
if (!renderer) //item is not displayed (scroll to view it)
continue;
p1 = new Point(renderer.x, renderer.y);
p2 = new Point(renderer.width, renderer.height);
p1 = renderer.parent.localToGlobal(p1);
p2 = renderer.localToGlobal(p2);
if(globalX >= p1.x && globalX <= p2.x && globalY >= p1.y && globalY <= p2.y)
return i;
}
return -1;
}
]]>
</mx:Script>
</mx:Application>