Übersicht über Drag & Drop
Aktualisiert: November 2007
Dieses Thema enthält eine Übersicht über die Drag & Drop-Unterstützung in Windows Presentation Foundation (WPF)-Anwendungen. Drag & Drop verweist im Allgemeinen auf eine Methode der Benutzeroberfläche (user interface, UI)-Interaktion, bei der mit einer Maus (oder anderen Zeigegeräten) ein oder mehrere Objekte ausgewählt, diese Objekte auf das gewünschte Ablageziel der Benutzeroberfläche gezogen und abgelegt werden.
Dieses Thema enthält folgende Abschnitte.
- Drag & Drop-Unterstützung in WPF
- Daten und Datenobjekte
- Drag & Drop-Ereignisse
- Arbeiten mit Datenobjekten
- Verwandte Abschnitte
Drag & Drop-Unterstützung in WPF
Bei Drag & Drop-Vorgängen sind normalerweise zwei Seiten beteiligt: eine Ziehquelle, von der das gezogene Objekt stammt, und ein Ablageziel, das das abgelegte Objekt erhält. Ziehquelle und Ablageziel können dieselbe oder eine unterschiedliche Anwendung sein.
Typ und Anzahl der Objekte, die mittels Drag & Drop bearbeitet werden können, sind vollständig beliebig. Eine oder mehrere Dateien bzw. ein oder mehrere Ordner und Inhaltsauswahl sind einige der häufigeren Objekte, die mithilfe von Drag & Drop-Vorgängen bearbeitet werden. Welche Aktionen bei einem Drag & Drop-Vorgang ausgeführt werden ist anwendungsspezifisch und hängt häufig vom Kontext ab. Beispielsweise werden beim Ziehen einer Dateiauswahl von einem Ordner zu einem anderen auf demselben Datenträger die Dateien standardmäßig verschoben. Werden Dateien hingegen von einer Universal Naming Convention (UNC)-Freigabe zu einem lokalen Ordner gezogen, werden die Dateien standardmäßig kopiert. Die von WPF bereitgestellten Drag & Drop-Funktionen wurden so entworfen, dass sie hochflexibel und anpassbar sind, um eine Vielzahl von Drag & Drop-Szenarien zu unterstützen. Drag & Drop unterstützt das Bearbeiten von Objekten innerhalb einer einzelnen Anwendung oder zwischen verschiedenen Anwendungen. Drag & Drop zwischen WPF-Anwendungen und anderen Windows-Anwendungen wird ebenfalls vollständig unterstützt. Drag & Drop fällt in den allgemeineren Bereich der Datenübertragung. Die Datenübertragung umfasst neben Drag & Drop die Verwendung der Systemzwischenablage für Kopier- und Einfügevorgänge.
Sicherheitshinweis: Drag & Drop per OLE funktioniert nicht in der Internetzone.
Daten und Datenobjekte
Daten, die als Teil eines Drag & Drop-Vorgangs übertragen werden, werden in einem Datenobjekt gespeichert. Im Prinzip besteht ein Datenobjekt aus einem oder mehreren der folgenden Paare:
einem Object, das die eigentlichen Daten enthält, sowie
einem entsprechenden Datenformatbezeichner
Die Daten selbst können aus allem bestehen, was als Basis-Object dargestellt werden kann. Das entsprechende Datenformat ist eine Zeichenfolge oder ein Type, der einen Hinweis auf das Format der Daten gibt. Datenobjekte unterstützen das Hosten mehrerer Datenpaare (bzw. Datenformatpaare), sodass ein einzelnes Datenobjekt Daten in mehreren Formaten bereitstellen kann.
Alle Datenobjekte müssen die IDataObject-Schnittstelle implementieren, die den folgenden Standardsatz von Methoden bereitstellt, mit denen sich die Datenübertragung durchführen und vereinfachen lässt.
Methode |
Zusammenfassung |
---|---|
Ruft ein Datenobjekt in einem bestimmten Datenformat ab. |
|
Überprüft, ob die Daten in einem bestimmten Format verfügbar sind oder in dieses Format konvertiert werden können. |
|
Gibt eine Liste von Formaten zurück, in denen die Daten in diesem Datenobjekt gespeichert sind bzw. in die diese konvertiert werden können. |
|
Speichert die angegebenen Daten in diesem Datenobjekt. |
WPF stellt eine grundlegende Implementierung von IDataObject in der DataObject-Klasse bereit. Die vordefinierte DataObject-Klasse ist für viele häufige Datenübertragungsszenarien ausreichend.
Informationen über vordefinierte, von WPF bereitgestellte Datenformate finden Sie im Referenzthema zur DataFormats-Klasse.
Datenobjekte enthalten häufig eine Funktion, um bei der Datenextraktion Daten automatisch aus einem Format in ein anderes Format zu konvertieren. Diese Funktion wird als automatische Konvertierung bezeichnet.
Beim Abfragen der in einem Datenobjekt verfügbaren Datenformate können automatisch konvertierbare Datenformate aus systemeigenen Datenformaten herausgefiltert werden, indem die GetFormats(Boolean)-Methode oder die GetDataPresent(String, Boolean)-Methode aufgerufen und der autoConvert-Parameter als false angegeben wird. Wenn einem Datenobjekt mit der SetData(String, Object, Boolean)-Methode Daten hinzugefügt werden, kann die automatische Konvertierung von Daten durch Festlegen des autoConvert-Parameters auf false verhindert werden.
Drag & Drop-Ereignisse
Drag & Drop-Vorgänge unterstützen ein ereignisgesteuertes Modell. Ziehquelle und Ablageziel verwenden einen Standardsatz von Ereignissen zum Behandeln von Drag & Drop-Vorgängen. Die folgende Tabelle bietet einen Überblick über die Standard-Drag & Drop-Ereignisse.
Ereignisse für die Ziehquelle
Ereignis |
Zusammenfassung |
---|---|
Dieses Ereignis tritt auf, wenn ein Drag & Drop-Vorgang gestartet wird. Es ermöglicht es dem Ablageziel, Feedbackinformationen an die Ziehquelle zu senden, die damit häufig die Darstellung des Mauszeigers dynamisch anpasst, um dem Benutzer Feedback zu geben. Hierbei handelt es sich um ein Bubbling-Ereignis. |
|
Dieses Ereignis tritt auf, wenn sich während eines Drag & Drop-Vorgangs der Zustand von Tastatur oder Maustasten ändert. Hierdurch kann die Ablagequelle den Drag & Drop-Vorgang abhängig vom Zustand der Tastatur bzw. Maustasten abbrechen. Hierbei handelt es sich um ein Bubbling-Ereignis. |
|
Tunneling-Version von GiveFeedback. |
|
Tunneling-Version von QueryContinueDrag. |
Ereignisse für das Ablageziel
Ereignis |
Zusammenfassung |
---|---|
Dieses Ereignis tritt auf, wenn ein Objekt in die Begrenzung des Ablageziels gezogen wird. Hierbei handelt es sich um ein Bubbling-Ereignis. |
|
Dieses Ereignis tritt auf, wenn ein Objekt aus der Begrenzung des Ablageziels gezogen wird. Hierbei handelt es sich um ein Bubbling-Ereignis. |
|
Dieses Ereignis tritt auf, wenn ein Objekt innerhalb der Begrenzung des Ablageziels gezogen (bewegt) wird. Hierbei handelt es sich um ein Bubbling-Ereignis. |
|
Dieses Ereignis tritt auf, wenn ein Objekt auf dem Ablageziel abgelegt wird. Hierbei handelt es sich um ein Bubbling-Ereignis. |
|
Tunneling-Version von DragEnter. |
|
Tunneling-Version von DragLeave. |
|
Tunneling-Version von DragOver. |
|
Tunneling-Version von Drop. |
Arbeiten mit Datenobjekten
In diesem Abschnitt werden allgemeine Techniken für das Erstellen von und Arbeiten mit Datenobjekten beschrieben.
Verwenden der DataObject-Konstruktoren
Die DataObject-Klasse stellt mehrere überladene Konstruktoren bereit, die das Auffüllen einer neuen DataObject-Instanz mit einem einzelnen Datenpaar (bzw. Datenformatpaar) erleichtern.
Im folgenden Beispielcode wird ein neues Datenobjekt erstellt. Außerdem wird mithilfe von einem der überladenen Konstruktoren (DataObject(String, Object)) das Datenobjekt mit einer Zeichenfolge und einem angegebenen Datenformat initialisiert. In diesem Fall wird das Datenformat durch eine Zeichenfolge angegeben. Die DataFormats-Klasse stellt einen Satz vordefinierter Typzeichenfolgen bereit. Das automatische Konvertieren der gespeicherten Daten wird standardmäßig zugelassen.
string stringData = "Some string data to store...";
string dataFormat = DataFormats.UnicodeText;
DataObject dataObject = new DataObject(dataFormat, stringData);
Weitere Beispiele für Code, mit dem ein Datenobjekt erstellt wird, finden Sie unter Gewusst wie: Erstellen eines Datenobjekts.
Speichern von Daten in mehreren Formaten
Ein einzelnes Datenobjekt kann Daten in mehreren Formaten speichern. Durch den strategischen Einsatz von mehreren Datenformaten innerhalb eines einzelnen Datenobjekts ist das Datenobjekt möglicherweise für eine größere Zahl von Ablagezielen geeignet, als wenn nur ein einzelnes Datenformat dargestellt werden könnte. Beachten Sie, dass eine Ziehquelle im Allgemeinen von den Datenformaten, die für mögliche Ablageziele geeignet sind, unabhängig sein muss.
Im folgenden Beispiel wird gezeigt, wie einem Datenobjekt mithilfe der SetData(String, Object)-Methode Daten in mehreren Formaten hinzugefügt werden.
DataObject dataObject = new DataObject();
string sourceData = "Some string data to store...";
// Encode the source string into Unicode byte arrays.
byte[] unicodeText = Encoding.Unicode.GetBytes(sourceData); // UTF-16
byte[] utf8Text = Encoding.UTF8.GetBytes(sourceData);
byte[] utf32Text = Encoding.UTF32.GetBytes(sourceData);
// The DataFormats class does not provide data format fields for denoting
// UTF-32 and UTF-8, which are seldom used in practice; the following strings
// will be used to identify these "custom" data formats.
string utf32DataFormat = "UTF-32";
string utf8DataFormat = "UTF-8";
// Store the text in the data object, letting the data object choose
// the data format (which will be DataFormats.Text in this case).
dataObject.SetData(sourceData);
// Store the Unicode text in the data object. Text data can be automatically
// converted to Unicode (UTF-16 / UCS-2) format on extraction from the data object;
// Therefore, explicitly converting the source text to Unicode is generally unnecessary, and
// is done here as an exercise only.
dataObject.SetData(DataFormats.UnicodeText, unicodeText);
// Store the UTF-8 text in the data object...
dataObject.SetData(utf8DataFormat, utf8Text);
// Store the UTF-32 text in the data object...
dataObject.SetData(utf32DataFormat, utf32Text);
Abfragen eines Datenobjekts nach verfügbaren Formaten
Da ein einzelnes Datenobjekt beliebig viele Datenformate enthalten kann, enthalten Datenobjekte Funktionen zum Abrufen einer Liste von verfügbaren Datenformaten.
Im folgenden Beispielcode wird mit der GetFormats-Überladung ein Zeichenfolgenarray abgerufen, das alle in einem Datenobjekt verfügbaren Datenformate (systemeigene und automatisch konvertierbare) angibt.
DataObject dataObject = new DataObject("Some string data to store...");
// Get an array of strings, each string denoting a data format
// that is available in the data object. This overload of GetDataFormats
// returns all available data formats, native and auto-convertible.
string[] dataFormats = dataObject.GetFormats();
// Get the number of data formats present in the data object, including both
// auto-convertible and native data formats.
int numberOfDataFormats = dataFormats.Length;
// To enumerate the resulting array of data formats, and take some action when
// a particular data format is found, use a code structure similar to the following.
foreach (string dataFormat in dataFormats)
{
if (dataFormat == DataFormats.Text)
{
// Take some action if/when data in the Text data format is found.
break;
}
else if(dataFormat == DataFormats.StringFormat)
{
// Take some action if/when data in the string data format is found.
break;
}
}
Weitere Beispiele für Code, mit dem ein Datenobjekt nach verfügbaren Datenformaten abgefragt wird, finden Sie unter Gewusst wie: Auflisten der Datenformate in einem Datenobjekt. Beispiele für die Abfrage eines Datenobjekts nach einem bestimmten vorhandenen Datenformat finden Sie unter Gewusst wie: Feststellen, ob ein Datenformat in einem Datenobjekt vorhanden ist.
Abrufen von Daten aus einem Datenobjekt
Wenn Daten aus einem Datenobjekt in einem bestimmten Format abgerufen werden, wird einfach eine der GetData-Methoden unter Angabe des gewünschten Datenformats aufgerufen. Mit einer der GetDataPresent-Methoden kann überprüft werden, ob ein bestimmtes Datenformat vorhanden ist. GetData gibt die Daten in einem Object zurück. Je nach Datenformat kann dieses Objekt in einen typspezifischen Container umgewandelt werden.
Im folgenden Beispielcode wird mit der GetDataPresent(String)-Überladung zunächst überprüft, ob ein angegebenes Datenformat verfügbar ist (im System oder durch automatische Konvertierung). Wenn das angegebene Format verfügbar ist, werden im Beispiel die Daten mit der GetData(String)-Methode abgerufen.
DataObject dataObject = new DataObject("Some string data to store...");
string desiredFormat = DataFormats.UnicodeText;
byte[] data = null;
// Use the GetDataPresent method to check for the presence of a desired data format.
// This particular overload of GetDataPresent looks for both native and auto-convertible
// data formats.
if (dataObject.GetDataPresent(desiredFormat))
{
// If the desired data format is present, use one of the GetData methods to retrieve the
// data from the data object.
data = dataObject.GetData(desiredFormat) as byte[];
}
Weitere Beispiele für Code, mit dem Daten aus einem Datenobjekt abgerufen werden, finden Sie unter Gewusst wie: Abrufen von Daten in einem bestimmten Datenformat.
Entfernen von Daten aus einem Datenobjekt
Daten können aus einem Datenobjekt nicht direkt entfernt werden. Um Daten aus einem Datenobjekt wirksam zu entfernen, gehen Sie folgendermaßen vor:
Erstellen Sie ein neues Datenobjekt, das nur die Daten enthält, die Sie beibehalten möchten.
"Kopieren" Sie die gewünschten Daten aus dem alten Datenobjekt in das neue Datenobjekt. Kopieren Sie die Daten mit einer der GetData-Methoden, um ein Object abzurufen, das die unformatierten Daten enthält. Fügen Sie anschließend mit einer der SetData-Methoden dem neuen Datenobjekt die Daten hinzu.
Ersetzen Sie das alte Datenobjekt durch das neue.
Tipp
Mit den SetData-Methoden werden einem Datenobjekt nur Daten hinzugefügt. Es werden damit keine Daten ersetzt, selbst wenn die Daten und das Datenformat mit einem vorhergehenden Aufruf vollständig übereinstimmen. Wenn SetData zweimal für dieselben Daten und dasselbe Datenformat aufgerufen wird, führt dies dazu, dass Daten und Datenformat zweimal im Datenobjekt vorhanden sind.