2010-03-22 76 views
2

如何防止拖动某些项目的List或DataGrid?Flex - 防止拖动某些项目

假设我有一个包含两个项目的列表:'Tom'和'Jerry'。只有'Tom'应该是可拖动的,而不是'Jerry'。

理想情况下,我有一个'isDragEnabled(item:Object):Boolean'函数,它正在被拖动源查询。

我的困难是,“的dragstart”事件,有到DragSource null值的事实开始,从一开始就这样对我很难找出拖动开始是关于什么的..

提前致谢!

PS已经有几次关于防止或取消掉落的讨论,但是我没有看到太多有关防止拖动开始的讨论,因此我们没有看到这个问题。

回答

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> 
2

你可以做两件事情:

  1. 您可以禁用列表中的物品都不能拖动,基于该selectedItem属性的数据对象上的属性。这会导致它们出现视觉障碍,您可能不想要,所以您也可以尝试...

  2. 当有效项目(基于selectedItem的数据)时,可以将列表的dragEnabled属性设置为“true”对象)被选中,当项目无效时为“false”。

+0

不错的选择Robusto,你有使用/测试过他们吗? 1似乎非常万无一失,但视觉上很烦人。 2看起来好像会起作用,但很多看起来应该为我工作的东西都不行。 – invertedSpear 2010-03-22 17:02:10

+0

我已经使用过他们,他们为我的公司工作。请注意,#1使用List的disabledFunction属性,而#2从dragDrop事件调用处理程序,该事件检查行是否有效拖动,如果该行无效,则调用event.stopImmediatePropagation()和event.preventDefault() 。 – Robusto 2010-03-22 19:06:31

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事件在拖动开始时被调度,因此如果您停止事件的传播,则可以避免拖动该项目。