Drag & Drop

Drag & Drop (Ziehen und Ablegen) stellt eine intuitive Möglichkeit zum Übertragen von Daten innerhalb einer Anwendung oder zwischen Anwendungen auf dem Windows-Desktop dar. Mit Drag & Drop können Benutzer*innen Daten zwischen Anwendungen oder innerhalb einer Anwendung mithilfe einer Standardgeste übertragen (Drücken-Halten-Ziehen mit dem Finger oder Drücken-Ziehen mit einer Maus oder einem Eingabestift).

Wichtige APIs:CanDrag-Eigenschaft, AllowDrop-Eigenschaft

Die Quelle für das Ziehen ist die Anwendung oder der Bereich, in der bzw. dem die Ziehbewegung ihren Ausgangspunkt hat. Sie stellt die zu übertragenden Daten bereit, indem ein Datenpaketobjekt gefüllt wird, das Standarddatenformate enthalten kann, einschließlich Text, RTF, HTML, Bitmaps, Speicherelemente oder benutzerdefinierte Datenformate. Die Quelle gibt auch die unterstützten Vorgänge an: Kopieren, Verschieben oder Verknüpfen. Durch das Loslassen wird der Drop-Vorgang (das Ablegen) ausgelöst. Das Drop-Ziel ist die Anwendung oder der Bereich unterhalb des Zeigers. Es verarbeitet das Datenpaket und gibt den Typ des ausgeführten Vorgangs zurück.

Während des Ziehens und Ablegens bietet die Benutzeroberfläche für das Ziehen einen visuellen Hinweis auf den Typ des ausgeführten Drag & Drop-Vorgangs. Dieses visuelle Feedback wird anfänglich von der Quelle bereitgestellt, kann aber von den Zielen geändert werden, wenn der Mauszeiger darüber bewegt wird.

Modernes Drag & Drop ist auf allen Geräten verfügbar, die UWP unterstützen. Es ermöglicht die Datenübertragung zwischen oder innerhalb von beliebigen Anwendungstypen, einschließlich klassischer Windows-Apps. In diesem Artikel geht es aber hauptsächlich um die XAML-API für modernes Drag & Drop. Nach der Implementierung stehen Drag & Drop-Vorgänge für sämtliche Richtungen (App zu App, App zu Desktop und Desktop zu App) zur Verfügung.

Im Folgenden finden Sie eine Übersicht darüber, welche Schritte Sie ausführen müssen, um Drag & Drop in Ihrer App zu aktivieren:

  1. Sie aktivieren das Ziehen für ein Element, indem Sie die CanDrag-Eigenschaft auf TRUE festlegen.
  2. Erstellen Sie das Datenpaket. Das System verarbeitet Bilder und Text automatisch, aber für andere Inhalte müssen Sie die Ereignisse DragStarting und DropCompleted behandeln, um damit Ihr eigenes Datenpaket zu erstellen.
  3. Sie aktivieren das Ablegen, indem Sie die AllowDrop-Eigenschaft für alle Elemente, die abgelegte Inhalte empfangen können, auf true festlegen.
  4. Behandeln Sie das DragOver-Ereignis, um dem System mitzuteilen, welche Typen von Ziehvorgängen das Element empfangen kann.
  5. Verarbeiten Sie das Drop-Ereignis, um den abgelegten Inhalt zu empfangen.

Aktivieren des Ziehens

Um das Ziehen für ein Element zu aktivieren, legen Sie die CanDrag-Eigenschaft auf true fest. Dadurch können das Element und die darin enthaltenen Elemente (im Fall von Auflistungen wie ListView) gezogen werden.

Legen Sie sehr genau fest, was gezogen werden kann. Ihre Benutzer*innen möchten nicht alles in Ihrer App ziehen, sondern nur bestimmte Elemente, z. B. Bilder oder Text.

Im Folgenden erfahren Sie, wie Sie CanDrag festlegen.

<Image x:Name="Image" CanDrag="True" Margin="10,292,10,0" Height="338"></Image>

Weitere Schritte müssen Sie nur ausführen, wenn Sie neben dem Aktivieren des Ziehens auch noch die Benutzeroberfläche anpassen möchten (dies wird weiter unten in diesem Artikel behandelt). Das Ablegen erfordert einige Schritte mehr.

Erstellen eines Datenpakets

In den meisten Fällen erstellt das System das Datenpaket für Sie. Das System behandelt Folgendes automatisch:

  • Bilder
  • Text

Für andere Inhalte müssen Sie die Ereignisse DragStarting und DropCompleted behandeln, um ein eigenes DataPackage zu erstellen.

Aktivieren des Ablegens

Das folgende Markup zeigt, wie Sie mithilfe von AllowDrop in XAML einen bestimmten Bereich der App als gültig für das Ablegen festlegen. Wenn Benutzer*innen versuchen, etwas an einer anderen Stelle abzulegen, lässt das System dies nicht zu. Wenn Sie möchten, dass Benutzer*innen Elemente an einer beliebigen Stelle in Ihrer App ablegen können, legen Sie den gesamten Hintergrund als Drop-Ziel fest.

<Grid AllowDrop="True" DragOver="Grid_DragOver" Drop="Grid_Drop"
      Background="LightBlue" Margin="10,10,10,353">
    <TextBlock>Drop anywhere in the blue area</TextBlock>
</Grid>

Behandeln des DragOver-Ereignisses

Das DragOver-Ereignis wird ausgelöst, wenn Benutzer*innen ein Element über Ihre App ziehen, ohne es abzulegen. In diesem Handler müssen Sie mithilfe der AcceptedOperation-Eigenschaft angeben, welche Vorgänge Ihre App unterstützt. Kopieren ist der am häufigsten verwendete Vorgang.

private void Grid_DragOver(object sender, DragEventArgs e)
{
    e.AcceptedOperation = DataPackageOperation.Copy;
}

Verarbeiten des Drop-Ereignisses

Das Drop-Ereignis tritt ein, wenn Benutzer*innen Elemente in einem gültigen Drop-Bereich loslassen. Sie verarbeiten sie mithilfe der DataView-Eigenschaft.

Aus Gründen der Einfachheit wird im folgenden Beispiel davon ausgegangen, dass die Benutzer*innen ein Einzelfoto abgelegt haben und direkt darauf zugreifen. In der Praxis können Benutzer*innen mehrere Elemente unterschiedlicher Formate gleichzeitig ablegen. Ihre App sollte diese Möglichkeit behandeln, indem sie überprüft, wie viele Dateien welcher Dateitypen abgelegt wurden, und diese entsprechend verarbeitet. Sie können die Benutzer*innen auch benachrichtigen, wenn sie versuchen, einen von Ihrer App nicht unterstützten Vorgang auszuführen.

private async void Grid_Drop(object sender, DragEventArgs e)
{
    if (e.DataView.Contains(StandardDataFormats.StorageItems))
    {
        var items = await e.DataView.GetStorageItemsAsync();
        if (items.Count > 0)
        {
            var storageFile = items[0] as StorageFile;
            var bitmapImage = new BitmapImage();
            bitmapImage.SetSource(await storageFile.OpenAsync(FileAccessMode.Read));
            // Set the image on the main page to the dropped image
            Image.Source = bitmapImage;
        }
    }
}

Anpassen der Benutzeroberfläche

Das System bietet eine Standardbenutzeroberfläche für Drag & Drop. Sie können jedoch auch verschiedene Teile der Benutzeroberfläche anpassen, indem Sie benutzerdefinierte Beschriftungen und Glyphen festlegen oder entscheiden, überhaupt keine Benutzeroberfläche anzuzeigen. Zum Anpassen der Benutzeroberfläche verwenden Sie die DragEventArgs.DragUIOverride-Eigenschaft.

private void Grid_DragOverCustomized(object sender, DragEventArgs e)
{
    e.AcceptedOperation = DataPackageOperation.Copy;
    e.DragUIOverride.Caption = "Custom text here"; // Sets custom UI text
    // Sets a custom glyph
    e.DragUIOverride.SetContentFromBitmapImage(
        new BitmapImage(
            new Uri("ms-appx:///Assets/CustomImage.png", UriKind.RelativeOrAbsolute)));
    e.DragUIOverride.IsCaptionVisible = true; // Sets if the caption is visible
    e.DragUIOverride.IsContentVisible = true; // Sets if the dragged content is visible
    e.DragUIOverride.IsGlyphVisible = true; // Sets if the glyph is visibile
}

Öffnen eines Kontextmenüs für ein Element, das mit Toucheingabe gezogen werden kann

Wenn Sie die Toucheingabe verwenden, werden für das Ziehen eines UIElement und das Öffnen des Kontextmenüs ähnliche Touchgesten verwendet, die jeweils mit dem Drücken und Halten beginnen. Hier sehen Sie, wie das System zwischen den beiden Aktionen für Elemente in Ihrer App unterscheidet, die beide Vorgänge unterstützen:

  • Wenn Benutzer*innen ein Element drücken und halten und innerhalb von 500 Millisekunden mit dem Ziehen beginnen, wird das Element gezogen, und das Kontextmenü wird nicht angezeigt.
  • Wenn die Benutzer*innen drücken und halten, aber nicht innerhalb von 500 Millisekunden mit dem Ziehen beginnen, wird das Kontextmenü geöffnet.
  • Wenn die Benutzer*innen versuchen, das Element zu ziehen (ohne den Finger zu heben), wird das Kontextmenü verworfen, und der Ziehvorgang wird gestartet.

Festlegen eines Elements in einer ListView oder GridView als Ordner

Sie können ein ListViewItem oder GridViewItem als Ordner festlegen. Dies ist besonders nützlich in Szenarien mit TreeView-Elementen und einem Datei-Explorer. Legen Sie dazu die AllowDrop-Eigenschaft für dieses Element explizit auf True fest.

Das System zeigt automatisch die entsprechenden Animationen zum Ablegen in einem Ordner an, und nicht die für Nicht-Ordner-Elemente. Ihr App-Code muss weiterhin das Drop-Ereignis für das Ordnerelement (sowie für Nicht-Ordner-Elemente) behandeln, um die Datenquelle zu aktualisieren und das abgelegte Element im Zielordner hinzuzufügen.

Aktivieren der Neuanordnung beim Drag & Drop in ListViews

ListView-Elemente unterstützen Drag & Drop standardmäßig, wobei eine API verwendet wird, die der in diesem Artikel beschriebenen CanDrop-API sehr ähnlich ist. Sie fügen mindestens die Eigenschaften AllowDrop und CanReorderItems hinzu.

Weitere Informationen finden Sie unter ListViewBase.CanReorderItems.

Implementieren von benutzerdefiniertem Drag & Drop

Die UIElement-Klasse erledigt die meisten Aufgaben für das Implementieren von Drag & Drop für Sie. Wenn Sie möchten, können Sie jedoch Ihre eigene Version mithilfe der unten aufgeführten APIs implementieren.

Funktionalität WinAppSDK-API und Microsoft.UI.Input.DragDrop-Namespace UWP-API
Windows.Applicationmodel.DataTransfer.DragDrop.Core-Namespace
DragPrimitive DragOperation CoreDragOperation
Erstellen eines Datenpakets DataPackage identisch
Übergeben von Ziehvorgängen an die Shell DragOperation.StartAsync CoreDragOperation.StartAsync
Empfangen von Ablegevorgängen aus der Shell DragDropManager.TargetRequested
ICoreDropOperationTarget
CoreDragDropManager.TargetRequested
ICoreDropOperationTarget

Siehe auch