2013-04-12 14 views
6

Vorrei consentire a un utente di riordinare gli elementi all'interno di una cartella ad albero Flex, ma non spostare quegli elementi all'esterno della cartella. Posso impedire che il drop esterno abbia successo, ma vorrei dare al feedback dell'utente (prima della caduta) che il drop non avrà successo. Ho trovato molti esempi riguardanti l'azione di rilascio, ma nulla che mostri il feedback corretto all'utente.Prevenzione del feedback di caduta dell'albero flessibile

In base alla documentazione Tree, dovrei essere in grado di chiamare DragManager.showFeedback(DragManager.NONE) durante l'evento dragOver, ma non funziona. Di seguito è riportato un breve progetto di esempio. C'è un modo per indicare all'utente durante un evento di trascinamento che la caduta non avrà successo?

Grazie in anticipo per qualsiasi soluzione!

<?xml version="1.0" encoding="utf-8"?> 
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" 
         width="354" 
         height="480"> 
    <fx:Script> 
     <![CDATA[ 
      import mx.collections.ArrayCollection; 
      import mx.core.IUIComponent; 
      import mx.core.mx_internal; 
      import mx.events.DragEvent; 
      import mx.events.FlexEvent; 
      import mx.managers.DragManager; 

      protected function tree_dragEnterHandler(event:DragEvent):void { 
       // only items can be dragged - not folders 
       if ([email protected] == "item") { 
        DragManager.acceptDragDrop(IUIComponent(event.currentTarget)); 
       } else { 
        event.preventDefault(); 
        DragManager.showFeedback(DragManager.NONE); 
       } 
      } 

      protected function tree_dragOverHandler(event:DragEvent):void { 
       var dropData:Object = tree.mx_internal::_dropData; 
       var dragItem:XML = event.dragSource.dataForFormat("treeItems")[0]; 
       if (!dropData || !dropData.parent || !dragItem.parent() || dragItem.parent() != dropData.parent) { 
        trace("preventing drop"); 
        DragManager.showFeedback(DragManager.NONE); 
        return; 
       } 
       trace("allowing drop"); 
       DragManager.showFeedback(DragManager.MOVE); 
      } 

      protected function tree_dragDropHandler(event:DragEvent):void { 
      } 
     ]]> 
    </fx:Script> 
    <fx:Declarations> 
     <fx:XML id="treeData"> 
      <folder id="root" 
        label="root" 
        type="root"> 
       <folder id="folder1" 
         label="Folder 1" 
         type="folder"> 
        <folder id="folder2" 
          label="Folder 2" 
          type="folder"> 
         <item id="item1" 
           label="Item 1" 
           type="item"/> 
         <item id="item2" 
           label="Item 2" 
           type="item"/> 
         <item id="item3" 
           label="Item 3" 
           type="item"/> 
         <item id="item4" 
           label="Item 4" 
           type="item"/> 
         <item id="item5" 
           label="Item 5" 
           type="item"/> 
        </folder> 
       </folder> 
       <folder id="folder3" 
         label="Folder 3" 
         type="folder"/> 
       <folder id="folder4" 
         label="Folder 4" 
         type="folder"/> 
       <folder id="folder5" 
         label="Folder 5" 
         type="folder"/> 
      </folder> 
     </fx:XML> 
    </fx:Declarations> 
    <mx:Tree id="tree" 
      left="29" 
      right="28" 
      top="28" 
      bottom="27" 
      dragEnabled="true" 
      dropEnabled="true" 
      dragMoveEnabled="true" 
      dataProvider="{treeData}" 
      labelField="@label" 
      dragEnter="tree_dragEnterHandler(event)" 
      dragOver="tree_dragOverHandler(event)" 
      dragDrop="tree_dragDropHandler(event)" 
      showRoot="false"> 
    </mx:Tree> 
</s:WindowedApplication> 
+0

provare a mettere tutta la tua logica in dragEnterHandler - documentazione afferma che DragEvent.DRAG_ENTER dovrebbe essere usato (non DragEvent.DRAG_OVER) –

+0

dragEnterHandler() solo viene chiamato una volta all'inizio del trascinamento. Voglio poter modificare il feedback durante il trascinamento, in base all'elemento sotto il cursore. –

+0

Questo sta accadendo perché mentre si imposta il feedback di trascinamento su "NONE" immediatamente dopo che il comportamento di trascinamento della struttura predefinito in Albero lo riporta su "MOVE". [Questa pagina] (http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7cfe.html) mostra due esempi di trascinamento della selezione, uno per i controlli non di elenco e uno per i controlli basati su elenchi (come l'albero). Nell'esempio basato sull'elenco, ti vengono assegnate 3 scelte: usa il comportamento incorporato, fai il rollover o usa una combinazione di entrambi. Lo stai facendo, quando imposti il ​​feedback di trascinamento su "NONE" viene sovrascritto dal comportamento predefinito. –

risposta

2

E 'frustrante che la funzionalità drag-and-drop di default quasi fornisce tutto il necessario per raggiungere questo obiettivo, ma non del tutto. Sembra che la risposta di IlyaZ dovrebbe funzionare, ma potrebbe trattarsi di un bug nel controllo mx di Tree: Tree.

Ho finito per realizzare questo rotolando la mia implementazione di drag-and-drop come accennato da SunilD. Il codice è incluso di seguito per chiunque possa incontrare lo stesso problema in futuro.

Nota che c'è ancora un piccolo problema feedback visivo quando l'utente sta trascinando il confine tra maxDropIndex e maxDropIndex+1: Nella parte inferiore del confine l'indicatore di caduta si sposterà per indicare che è possibile lasciare un oggetto alla cartella livello. Sto ancora cercando una buona soluzione a questo (qualcuno può indicarmi la fonte dell'albero?).

<?xml version="1.0" encoding="utf-8"?> 
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" 
         width="354" 
         height="480"> 
    <fx:Script> 
     <![CDATA[ 
      import mx.collections.ArrayCollection; 
      import mx.core.DragSource; 
      import mx.core.IUIComponent; 
      import mx.core.mx_internal; 
      import mx.events.DragEvent; 
      import mx.events.FlexEvent; 
      import mx.managers.DragManager; 

      protected var dragging:Boolean = false; 
      protected var minDropIndex:int = 0; 
      protected var maxDropIndex:int = 0; 

      protected function tree_dragEnterHandler(event:DragEvent):void { 
       // only items can be dropped 
       if (event.dragSource.hasFormat("tree_item_node")) { 
        DragManager.acceptDragDrop(IUIComponent(event.currentTarget)); 
        trace("accepting DragDrop"); 
       } else { 
        event.preventDefault(); 
        DragManager.showFeedback(DragManager.NONE); 
        trace("rejecting DragDrop"); 
       } 
      } 

      protected function tree_dragOverHandler(event:DragEvent):void { 
       var index:int = tree.calculateDropIndex(event); 
       if (index < minDropIndex || index > maxDropIndex) { 
        trace("preventing drop"); 
        DragManager.showFeedback(DragManager.NONE); 
        this.tree.hideDropFeedback(event); 
        return; 
       } 
       trace("allowing drop"); 
       DragManager.showFeedback(DragManager.MOVE); 
       this.tree.showDropFeedback(event); 
      } 

      protected function tree_dragDropHandler(event:DragEvent):void { 
       trace("dragDropHandler"); 
      } 

      protected function tree_mouseMoveHandler(event:MouseEvent):void { 
       // see if we should start a drag operation 
       if (event.buttonDown && !dragging && tree.selectedItem && [email protected] == "item") { 
        // TODO: calculate the min and max drag indices from currently-selected index 
        minDropIndex = 2; 
        maxDropIndex = 7; 

        // start the drag 
        dragging = true; 
        var dragSource:DragSource = new DragSource(); 
        dragSource.addData(tree.selectedItem, "tree_item_node"); 
        DragManager.doDrag(IUIComponent(event.currentTarget), dragSource, event); 
       } 
      } 

      protected function tree_dragCompleteHandler(event:DragEvent):void { 
       trace("dragComplete: no longer dragging"); 
       this.tree.hideDropFeedback(event); 
       dragging = false; 
      } 
     ]]> 
    </fx:Script> 
    <fx:Declarations> 
     <fx:XML id="treeData"> 
      <folder id="root" 
        label="root" 
        type="root"> 
       <folder id="folder1" 
         label="Folder 1" 
         type="folder"> 
        <folder id="folder2" 
          label="Folder 2" 
          type="folder"> 
         <item id="item1" 
           label="Item 1" 
           type="item"/> 
         <item id="item2" 
           label="Item 2" 
           type="item"/> 
         <item id="item3" 
           label="Item 3" 
           type="item"/> 
         <item id="item4" 
           label="Item 4" 
           type="item"/> 
         <item id="item5" 
           label="Item 5" 
           type="item"/> 
        </folder> 
       </folder> 
       <folder id="folder3" 
         label="Folder 3" 
         type="folder"/> 
       <folder id="folder4" 
         label="Folder 4" 
         type="folder"/> 
       <folder id="folder5" 
         label="Folder 5" 
         type="folder"/> 
      </folder> 
     </fx:XML> 
    </fx:Declarations> 
    <mx:Tree id="tree" 
      left="29" 
      right="28" 
      top="28" 
      bottom="27" 
      dragEnabled="false" 
      dropEnabled="false" 
      dataProvider="{treeData}" 
      labelField="@label" 
      dragEnter="tree_dragEnterHandler(event)" 
      dragOver="tree_dragOverHandler(event)" 
      dragDrop="tree_dragDropHandler(event)" 
      dragComplete="tree_dragCompleteHandler(event)" 
      mouseMove="tree_mouseMoveHandler(event)" 
      showRoot="false"> 
    </mx:Tree> 
</s:WindowedApplication> 
Problemi correlati