2013-04-12 32 views
6

Chciałbym umożliwić użytkownikowi zmianę kolejności elementów w folderze drzewa Flex, ale nie przenosić tych elementów poza folder. Mogę zapobiec powodzeniu z zewnatrz, ale chciałbym dać informację zwrotną od użytkownika (przed zrzutem), że upuszczenie się nie powiedzie. Znalazłem wiele przykładów dotyczących akcji upuszczania, ale nic, co pokazuje poprawną informację zwrotną dla użytkownika.Zapobieganie zgłaszaniu upuszczania drzewa Flex

Zgodnie z dokumentacją drzewa, powinienem zadzwonić pod numer DragManager.showFeedback(DragManager.NONE) podczas imprezy , ale to nie działa. Krótki przykładowy projekt znajduje się poniżej. Czy istnieje sposób wskazania użytkownikowi podczas zdarzenia przeciągania, że ​​zrzut się nie powiedzie?

Z góry dziękuję za rozwiązanie!

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

Spróbuj umieścić całą swoją logikę w dragEnterHandler - dokumentacja wskazuje, że DragEvent.DRAG_ENTER powinny być stosowane (nie DragEvent.DRAG_OVER) –

+0

dragEnterHandler() jest wywoływana tylko raz na początku ulicy. Chcę mieć możliwość zmiany sprzężenia zwrotnego podczas przeciągania, w oparciu o element pod kursorem. –

+0

Dzieje się tak, ponieważ podczas ustawiania sprzężenia zwrotnego przeciągania na "BRAK" natychmiast po utworzeniu przeciągnij i upuść zachowanie drzewa ustawia go z powrotem na "PRZESUŃ". [Ta strona] (http://help.adobe.com/pl/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7cfe.html) pokazuje dwa przykłady przeciągania i upuszczania, jeden dla elementów sterujących bez listy i jeden dla elementów sterujących opartych na listach (np. drzewo). W przykładzie opartym na liście masz do wyboru 3 opcje: użyj wbudowanego zachowania, wykonaj własne lub użyj kombinacji obu. Robisz to drugie, po ustawieniu sprzężenia zwrotnego przeciągania na "NONE" zostanie on przesłonięty przez domyślne zachowanie. –

Odpowiedz

2

To frustrujące, że domyślna funkcjonalność drag-and-drop prawie zapewnia wszystko, co niezbędne do osiągnięcia tego celu, ale nie całkiem. Wygląda na to, że odpowiedź Ilya powinna działać, ale może to być błąd w kontrolce mx: Tree systemu Flex.

Skończyłem to, wykonując własną implementację "przeciągnij i upuść", o czym wspomniał SunilD. Poniższy kod jest dostępny dla każdego, kto może napotkać ten sam problem w przyszłości.

Należy pamiętać, że jest jeszcze mały wizualny problem sprzężenia zwrotnego, gdy użytkownik jest przeciągnięcie na pograniczu maxDropIndex i maxDropIndex+1: Na dolnej części granicy wskaźnik spadku przesunie się wskazywać, że jest to możliwe, aby upuścić element w folderze poziom. Wciąż szukam dobrego rozwiązania tego problemu (czy ktoś może wskazać mi źródło drzewa?).

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