VB.NET-Tipp 0043: Drag & Drop mit .NET
von Daniel Noll
Beschreibung
Dieses Beispiel zeigt, wie einfach sich Drag & Drop mit .NET-Bordmitteln verwirklichen lässt.
Schwierigkeitsgrad: | Framework-Version(en): .NET Framework 1.0, .NET Framework 1.1, .NET Framework 2.0, .NET Framework 3.0, .NET Framework 3.5 | .NET-Version(en): Visual Basic 2002, Visual Basic 2003, Visual Basic 2005, Visual Basic 2008 | Download: |
' Dieser Quellcode stammt von http://www.activevb.de ' und kann frei verwendet werden. Für eventuelle Schäden ' wird nicht gehaftet. ' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. ' Ansonsten viel Spaß und Erfolg mit diesem Source! ' Projektversion: Visual Studio 2002/2003 ' Option Strict: Aus ' Option Explicit: An ' ' Referenzen: ' - System ' - System.Data ' - System.Drawing ' - System.Windows.Forms ' - System.XML ' ' Imports: ' - Microsoft.VisualBasic ' - System ' - System.Collections ' - System.Data ' - System.Drawing ' - System.Diagnostics ' - System.Windows.Forms ' ' ############################################################################## ' ############################# frmDragAndDrop.vb ############################## ' ############################################################################## Option Strict On Public Class frmDragAndDrop Inherits System.Windows.Forms.Form ' Diese Struktur löst das Problem, dass man ein Element in die selbe ' Listbox verschiebt, in dem es eine Owner-Eigenschaft hinzufügt, die vor ' ' dem Hinzufügen überprüft wird. Dank der ToString-Funktion wird in der ' ' Listbox der von uns angegebene Text ausgegeben Private Class ListBoxItem Public text As String Public owner As ListBox Public Overrides Function ToString() As String Return "Element: " & text End Function Public Sub New(ByVal name As String, ByVal owner As ListBox) Me.text = name Me.owner = owner End Sub End Class ' Wird eine Listbox verschoben? Private ControlMove As Boolean Private Sub frmDragAndDrop_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ' Drag & Drop sowohl für die Listboxen (d.h. die Items) ' als auch die Form (die Controls) aktivieren lstBox1.AllowDrop = True lstBox2.AllowDrop = True Me.AllowDrop = True ' Ein paar Testeinträge in die Listbox hinzufügen Dim i As Integer For i = 0 To 5 lstBox1.Items.Add(New ListBoxItem(i.ToString, lstBox1)) lstBox2.Items.Add(New ListBoxItem(i.ToString, lstBox2)) Next End Sub Private Sub Listbox_Move(ByVal sender As Object, _ ByVal e As DragEventArgs) _ Handles MyBase.DragOver, lstBox1.DragOver, lstBox2.DragOver ' Wenn ein Drag&Drop-Vorgang für eine Listbox gestartet ist ... If ControlMove Then Dim ctrl As Control = _ DirectCast(e.Data.GetData(GetType(ListBox)), ListBox) ' ... das Control immer an die Position verschieben ctrl.Location = Me.PointToClient(New Point(e.X, e.Y)) End If End Sub Private Sub ListBox_MouseDown(ByVal sender As Object, _ ByVal e As System.Windows.Forms.MouseEventArgs) _ Handles lstBox1.MouseDown, lstBox2.MouseDown ' Dadurch, dass wir mit dem Ereignis gleich zwei Controls abfangen, ' können wir uns Wiederholungen sparen Dim box As ListBox = DirectCast(sender, ListBox) If e.Button = MouseButtons.Right Then ' Drag&Drop für die ListBox starten, wenn die rechte Maustaste ' gedrückt ist ControlMove = True Me.DoDragDrop(box, DragDropEffects.Move) ElseIf box.SelectedIndex <> -1 Then ' Drag&Drop für ein ListBoxItem starten, sofern denn eins markiert ' ist box.DoDragDrop(box.Items(box.SelectedIndex), _ DragDropEffects.Move) End If End Sub Private Sub ListBox_DragEnter(ByVal sender As Object, _ ByVal e As System.Windows.Forms.DragEventArgs) _ Handles lstBox1.DragEnter, lstBox2.DragEnter If e.Data.GetDataPresent(GetType(ListBoxItem)) Then ' Wenn ein ListBoxItem vorhanden ist, dann den ' Drop-Vorgang erlauben. Die Kontrolle auf ein ' ListBoxItem ist notwendig, weil sonst "alles" ' in die ListBox verschoben werden könnte, ' was schließlich im Drop-Ereignis einen Fehler ' zur Folge hätte. e.Effect = DragDropEffects.Move End If End Sub Private Sub ListB_DragDrop(ByVal sender As Object, _ ByVal e As DragEventArgs) _ Handles MyBase.DragDrop, lstBox1.DragDrop, lstBox2.DragDrop ' Dies ist das Drop-Ereignis für die Controls. ' Wenn also das Control "gedropt" wurde, ' ControlMove auf False setzen If ControlMove = True Then ControlMove = False End Sub Private Sub ListBox_DragDrop(ByVal sender As Object, _ ByVal e As System.Windows.Forms.DragEventArgs) _ Handles lstBox2.DragDrop, lstBox1.DragDrop Dim box As ListBox = DirectCast(sender, ListBox) Dim item As ListBoxItem ' Nochmal auf den richtigen Datentyp prüfen If e.Data.GetDataPresent(GetType(ListBoxItem)) Then item = DirectCast(e.Data.GetData(GetType(ListBoxItem)), ListBoxItem) If Not item.owner Is sender Then ' Das Element in die Listbox hinzufügen ... box.Items.Add(item) ' und in der anderen Löschen If box Is lstBox1 Then lstBox2.Items.Remove(item) Else lstBox1.Items.Remove(item) End If item.owner = box End If End If End Sub End Class
Ihre Meinung
Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.
Archivierte Nutzerkommentare
Klicken Sie diesen Text an, wenn Sie die 3 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.
Kommentar von Sascha Bendler am 13.01.2008 um 08:02
Hallo,
danke für das tolle Beispiel. Eine kleine Verbessung würde ich gerne empfehlen, damit beim Rechts-Klick die Listbox nicht so springt Ihr Beispiel um folgendes ergänzen:
nach der Zeile >>Private ControlMove As Boolean<<
diese 2 Zeilen einfügen:
Private mouseX As Integer
Private mouseY As Integer
und in der Sub Listbox_move die Zeile
ctrl.Location = Me.PointToClient(New Point(e.X, e.Y))
ändern in
ctrl.Location = Me.PointToClient(New Point(e.X - mouseX, e.Y - mouseY)) ' subtrahiere gemerkte Mausposition
und als letzte Ergänzung in der Sub-Routine Listbox_MouseDown nach folgender Zeile
>>ControlMove = True
diese hier hinzufügen:
mouseX = e.X 'merke X-Koord. Mauspos.
mouseY = e.Y 'merke Y-Koord. Mauspos.
fertig.
Wie gesagt toller Tipp und auch von mir ein herzlichen Dank für den SINNVOLLEN BEITRAG im Internet.
Viele Grüße
Sascha
Kommentar von vbnetentwickler am 25.10.2006 um 18:25
Hi!
Toller Tipp! Aber wie kann man Items an einer bestimmten Stelle einfügen bzw. untergeordnet einfügen (TreeView)?
Grüße,
Eric
Kommentar von Timo am 03.10.2006 um 10:12
Super Tipp.
Ich musste laut VS noch
If e.Button = MouseButtons.Right Then
in
If e.Button = Windows.Forms.MouseButtons.Right Thenumschreiben.
Bin sehr dankbar um den Tipp!