2 Stimmen

Wie kann man in Flex 3 eine Drag-and-Drop-Operation abbrechen bzw. nicht akzeptieren?

Das Ziel: Ermöglichen Sie es dem Benutzer, einen Datensatz zu löschen, indem er eine Zeile aus einem AdvancedDataGrid auf ein Mülleimer-Symbol zieht und über ein Popup-Fenster mit den Schaltflächen "OK" und "Abbrechen" prüft, ob der Benutzer dies beabsichtigt hat.

Was funktioniert:

  • Ziehen/Loslassen einer Zeile auf das Papierkorbsymbol.
  • Wenn der Benutzer auf die Schaltfläche "OK" klickt, wird der Datensatz gelöscht.
  • Wenn der Benutzer auf die Schaltfläche "Abbrechen" klickt, wird der Vorgang abgebrochen.

Problem: Nachdem der Benutzer auf die Schaltfläche "Abbrechen" geklickt hat und die Popup-Warnung geschlossen wurde, können keine Zeilen in der ADG mehr gezogen werden. Ich habe herausgefunden, dass der Benutzer nach dem Sortieren der ADG durch Klicken auf eine Spaltenüberschrift wieder mit dem Ziehen von Zeilen beginnen kann.

Code: (geändert vom ursprünglichen Beitrag)

<mx:Image source="{trashImage}" buttonMode="true" 
toolTip="drag a participant here to delete them from the project"
dragDrop="deleteParticipantDrop(event)" dragEnter="deleteParticipantEnter(event)" 
dragExit="deleteParticipantDragExit(event)" top="4" right="122" id="image2" />  

// trashImage Event Handlers:
private function deleteParticipantEnter(event:DragEvent):void
{
    var component:IUIComponent = IUIComponent(event.currentTarget);
    dragComponent = component;
    DragManager.acceptDragDrop(component);
    DragManager.showFeedback(DragManager.MOVE);
    deleteParticipantDragEvent = event;
}

private function deleteParticipantDrop(event:DragEvent):void
{
    var selectedKitNum:String = memberRpt.selectedItem.KitNum;
    var selectedName:String = memberRpt.selectedItem.ParticipantName;
    var component:IUIComponent = IUIComponent(event.currentTarget);
    dragComponent = component;
    DragManager.acceptDragDrop(component);
    isEditingParticipantInfo = false;
    isDeletingParticipant = true;
    deleteParticipantDropEvent = event;
    event.stopImmediatePropagation(); // Added as per mrm
    alert.confirm("Are you sure you want to delete this participant, Kit #" + memberRpt.selectedItem.KitNum + " ("  + 
        memberRpt.selectedItem.ParticipantName + ") from the project?  This cannot be reversed!!  An email will be " +
        "sent to notify this participant and you will receive a copy of it for your records.", confirmRemoveParticipant);
}

private function deleteParticipantDragExit(event:DragEvent):void
{
    var component:IUIComponent = IUIComponent(event.currentTarget);
    dragComponent = component;
    DragManager.acceptDragDrop(component);
    DragManager.showFeedback(DragManager.NONE);
}

private function confirmRemoveParticipant(event:CloseEvent):void
{
    if (event.detail == Alert.YES)
    {
        deleteReason = DeleteParticipantTitleWindow(PopUpManager.createPopUp( this, DeleteParticipantTitleWindow , true));
        dispatchEvent(deleteParticipantDropEvent); // Added as per mrm
        PopUpManager.centerPopUp(deleteReason);
        deleteReason.showCloseButton = true;
        deleteReason.title = "Reason for removal from project";
        deleteReason.addEventListener("close", cleanupRemoveParticipant);
        deleteReason["cancelButton"].addEventListener("click", cleanupRemoveParticipant);
        deleteReason["okButton"].addEventListener("click", finalizeDeleteParticipant);
        isDeletingParticipant = false; 
    }
    else
    {
        cleanupRemoveParticipant();
    }
}

private function cleanupRemoveParticipant(event:Event = null):void
{
    memberRpt.invalidateDisplayList();
    memberRpt.executeBindings();
    if (deleteReason != null)
    {
        PopUpManager.removePopUp(deleteReason);
        deleteReason = null;
    }
}

public function finalizeDeleteParticipant(event:Event):void
{
    if (deleteReason.reason.text != null)
    {
        selectedReportItem = memberRpt.selectedItem;
        selectedReportItemIndex = memberRpt.selectedIndex;
        memberReportData.removeItemAt(selectedReportItemIndex);
    }
    else
    {
        alert.info("You must provide a reason for removing a participant from your project!!");
    }

    cleanupRemoveParticipant();
}

Vielen Dank im Voraus für alle hilfreichen Vorschläge.

1voto

defmeta Punkte 1322

Haben Sie versucht, die Methode validateNow() auf dem ADG nach dem Abbruchereignis auszuführen?

Hier finden Sie weitere Informationen über die Methode validateNow().

Warum Sie über validateNow Bescheid wissen müssen...

Ich glaube wirklich, dass dies das ist, wonach Sie suchen! Bitte lassen Sie uns wissen, ob das der Fall ist...

0voto

Simon Punkte 74705

Versuchen Sie, die Datenbindungen in der Datentabelle mit executeBindings und/oder invalidateDisplayList im umschließenden Steuerelement zu aktualisieren.

Um ehrlich zu sein, klingt das ein wenig nach einem Fehler. Haben Sie dies auf flexcoders ? Die Jungs von Adobe treiben sich dort herum (wahrscheinlich auch hier, aber definitiv dort)

0voto

Simon Punkte 74705

Bleiben Sie dran... ich habe gerade festgestellt, dass zwischen dem Drop-Ereignis und der Schaltfläche "Abbrechen" des Popup-Fensters ein asynchroner Webservice-Aufruf erfolgt, der anscheinend von GetParticipantOrderInformation verarbeitet wird. Ist das korrekt?

Wenn ja, haben Sie dann versucht, einen einfacheren Dialog für Abbrechen anzubieten, bevor Sie das tun? Ich frage mich, ob die Kombination von Ereignisebenen ein Problem verursacht.

0voto

Sean Staats Punkte 297

Ich hatte keinen Erfolg mit dem Aktualisieren der Datenbindungen in der Datentabelle über die Methoden executeBindings und invalidateDisplayList. Auch die Anzeige der Bestätigungsmeldung vor dem Aufruf des Webservice brachte keinen Erfolg. Tatsächlich habe ich festgestellt, dass der Webservice-Aufruf völlig unnötig war, und habe ihn entfernt. Jetzt läuft der Code also wie folgt ab:

  1. Ziehen Sie die ADG-Zeile auf das Papierkorbsymbol.
  2. Bestätigungs-Warnungsfenster anzeigen.
  3. Wenn der Benutzer auf die Schaltfläche "Abbrechen" geklickt hat, wird die ADG erneut angezeigt.

Aber das gleiche Problem bleibt bestehen. Ich aktualisiere die Code Abschnitt mit dem neuesten Code.

0voto

mrm Punkte 209

Hier ist eine Idee: - Kurz bevor Sie das Alarmfenster erstellen, stoppen Sie das DragEvent

event.stopImmediatePropagation();
  • das Ereignis speichern, damit wir fortfahren können, wenn der Benutzer auf die Schaltfläche "Ja" klickt

    queuedEvent = event as DragEvent;

  • das Alarmfenster anzeigen

  • wenn der Benutzer auf die Schaltfläche "Ja" klickt, wird das Ereignis in der Warteschlange fortgesetzt

    dispatchEvent(queuedEvent);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X