2010-03-22 124 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事件在拖動開始時被調度,因此如果您停止事件的傳播,則可以避免拖動該項目。