Um die in einem TreeView-Steuerelement angezeigten Daten am einfachsten umzuorganisieren, ist Drag and Drop die einfachste Methode. Der Benutzer kann so eine Kategorie von der einen übergeordneten Kategorie zu einer anderen verschieben, Hauptkategorien anderen Kategorien unterordnen oder Unterkategorien zu Hauptkategorien machen. Dieser Artikel zeigt, wie Sie das Drag and Drop in unser Beispiel zur Verwaltung von Kategorien und Unterkategorien einbauen.
Beispieldatenbank
Die Beispiele dieses Artikels finden Sie in der Datenbank 2001_KategorienDragAndDrop.accdb.
Voraussetzungen
Damit Drag and Drop wie hier beschrieben funktioniert, müssen Sie zwei Einstellungen für das TreeView-Steuerelement vornehmen. Dies erledigen wir in der Beispieldatenbank in der Prozedur Form_Load:
Private Sub Form_Load() Set m_TreeView = Me!ctlTreeview.Object With objTreeView ... .OLEDragMode = ccOLEDragAutomatic .OLEDropMode = ccOLEDropManual End With ... End Sub
Wir verwenden das TreeView, das wir im Artikel Kategorien per TreeView verwalten erstellt haben, als Basis für die Beispiele dieses Artikels (siehe Bild 1).
Bild 1: Formular-Entwurf unseres Beispielformulars
Schritte im Drag and Drop-Vorgang
Der Start des Drag and Drop-Vorgangs erfolgt, wenn der Benutzer die linke Maustaste auf einem Element des TreeView-Steuerelements niederdrückt und das angeklickte Element dann mit der Maus an eine andere Stelle zieht. In diesem Moment wird das Ereignis OLEStartDrag ausgelöst.
Zu diesem Zeitpunkt können Sie erfassen, welches Element der Benutzer ziehen will. Solange er das Element nicht loslässt, wird ständig das Ereignis OLE-Drag-Over ausgelöst. Das können Sie dazu nutzen, die gerade überfahrenen potenziellen Ziele zum Loslassen des Elements optisch hervorzuheben.
Wenn der Benutzer die Maus mit dem gezogenen Element schließlich zur Zielposition bewegt hat und er die Maustaste loslässt, feuert das Ereignis OLEDragDrop. Hier ist dann die Gelegenheit, zu ermitteln, auf welches Element der Benutzer das Element fallen lässt und notwendige Schritte durchzuführen. Operationen wie etwa das ändern der übergeordneten Kategorie erfolgen nicht automatisch nur durch das Ziehen eines Elements an eine andere Position.
Ereignisprozeduren anlegen
Wir wollen zunächst die drei Ereignisprozeduren anlegen, die wir für das Implementieren der Drag and Drop-Funktion benötigen. Dazu wählen Sie im Klassenmodul des Formulars oben im linken Kombinationsfeld den Eintrag mit dem Namen des Steuerelements aus, hier also ctlTreeView. Das rechte Kombinationsfeld zeigt dann alle Ereignisse an, die für dieses Steuer-element zur Verfügung stehen (siehe Bild 2).
Bild 2: Anlegen der Ereignisprozeduren
Wählen Sie hier nacheinander die Einträge OLEDragDrop, OLEDragOver und OLEStartDrag auf, um die drei Ereignisprozeduren anzulegen.
Vorarbeit für Drag and Drop
Um einen Drag and Drop sauber einzuleiten, müssen Sie beim Start des Vorgangs genau ermitteln, welches Element der Benutzer ziehen will. Normalerweise ermitteln Sie das angeklickte Element mit der Eigenschaft SelectedItem. Das geschieht aber erst nach dem Loslassen der Maustaste. Beim Drag and Drop drücken Sie aber die Maustaste herunter und ziehen dann das Element an die gewünschte Stelle. Das heißt, dass das zu bewegende Element nicht zuverlässig markiert ist. Es kann auch sein, dass das Element, das zuvor markiert war, nun von Selected-Item geliefert wird.
Sie müssen also entweder vor dem Drag and Drop einmal einen vollständigen Mausklick auf das Element tätigen, um dieses zunächst sicher zu markieren. Oder Sie ergänzen unsere Prozedur, die wir im oben genannten Artikel zum Anzeigen der Kontextmenüs erstellt haben, um zwei Codezeilen. Diese Prozedur wird durch das Ereignis MouseDown ausgelöst (siehe Listing 1). Wir stellen hier die Eigenschaft SelectedItem auf das Element ein, das wir mit der Eigenschaft HitTest für die mit den Parametern x und y gelieferten Koordinaten ermitteln. HitTest(x,y) liefert das Element, das sich beim Herunterdrücken der Maustaste genau unter dem Mauszeiger befindet.
Private Sub ctlTreeView_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Long, ByVal y As Long) ... Select Case Button Case acRightButton ... Case acLeftButton objTreeView.SelectedItem = objTreeView.HitTest(x, y) End Select End Sub
Listing 1: Markieren des angeklickten Elements
Damit ausgestattet ist nun sicher das Element markiert, das sich beim Start des Drag and Drop-Vorgangs unter dem Mauszeiger befindet.
Das Data-Objekt
Wenn Sie sich die Signaturen der drei Ereignisprozeduren ansehen, erkennen Sie einen gemeinsamen Parameter, nämlich Data.
Dies ist das Herzstück des Drag and Drop-Vorgangs. Mit ihm können Sie nämlich beim Start des Ziehens eine Information festlegen, die Sie beim Fallenlassen des Elements noch abfragen können. In unserem Fall nutzen wir dies, um den Wert der Eigenschaft Key des gezogenen Node-Elements zu speichern – und somit die eindeutige Identifizierung dieses Elements. Das Data-Objekt stellt zum Speichern der Information die Methode SetData zur Verfügung, mit der Sie den Inhalt und den Typ des Inhalts festlegen können.
Auch die Prozeduren für die Ereignisse OLEDragOver und OLEDragDrop stellen den Data-Parameter zur Verfügung. Hier wollen Sie den enthaltenen Wert eher abfragen als setzen, deshalb stellt das Data-Objekt die Funktion GetData zur Verfügung.
Diese erwartet den Typ der zu ermittelnden Information, hier durch die Konstante ccCFText gekennzeichnet.
Starten des Drag and Drop-Vorgangs
Damit steigen wir in die beim Ziehen des Mauszeigers bei gedrückter Maustaste ausgelöste Ereignisprozedur ein, nämlich ctlTreeView_OLEStartDrag (siehe Listing 2). Hier stellen wir zunächst die Variable objNode auf das aktuell ausgewählte Element ein, das wir mit objTreeView.SelectedItem ermitteln. Ist objNode danach leer, beenden wir die Prozedur mit der Exit Sub-Anweisung.
Private Sub ctlTreeView_OLEDragOver(Data As Object, Effect As Long, Button As Integer, Shift As Integer, x As Single, _ y As Single, State As Integer) Dim strData As String Dim strDatatype As String If Data.GetFormat(ccCFText) = False Then Exit Sub End If strData = Data.GetData(ccCFText) strDatatype = Left(strData, 1) Select Case strDatatype Case "k" Set objTreeView.DropHighlight = objTreeView.HitTest(x, y) End Select End Sub
Listing 2: Diese Methode wird mehrfach während des Drag and Drop ausgelöst.
Anderenfalls leeren wir das Data-Objekt mit der Clear-Methode und weisen diesem mit der SetData-Methode einen Text zu, und zwar den Wert der Eigenschaft Key des Objekts aus objNode.
Der zweite Parameter erhält eine Konstante, die angibt, um welche Art von Information es sich bei dem beim Start von Drag and Drop übergebenen Wert handelt – hier ccCFText für einen Text.
Mit dem zweiten Parameter AllowedEffects können wir noch festlegen, welche Effekte später erlaubt sind. Es gibt die folgenden:
- ccOLEDropEffectCopy (1): Das Symbol für den Mauszeiger wird um einen Rahmen und ein Plus-Zeichen ergänzt (+).
- ccOLEDropEffectMove (2): Das Symbol für den Mauszeiger wird um einen Rahmen ergänzt.
- ccOLEDropEffectNone (0): Es wird beim Versuch, zu ziehen, keine Veränderung des Mauszeigers angezeigt und es erfolgt auch kein Drag and Drop.
- ccOLEDropEffectScroll (-2.147.483.648): Hierzu konnten wir keine Dokumentation finden.
Möchten Sie weiterlesen? Dann lösen Sie Ihr Ticket!
Hier geht es zur Bestellung des Jahresabonnements des Magazins Access [basics]:
Zur Bestellung ...
Danach greifen Sie sofort auf alle rund 400 Artikel unseres Angebots zu - auch auf diesen hier!
Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein: