Die Community zu .NET und Classic VB.
Menü

VB.NET-Tipp 0043: Drag & Drop mit .NET

 von 

Beschreibung

Dieses Beispiel zeigt, wie einfach sich Drag & Drop mit .NET-Bordmitteln verwirklichen lässt.

Schwierigkeitsgrad:

Schwierigkeitsgrad 1

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:

Download des Beispielprojektes [4,94 KB]

' 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 Then
umschreiben.

Bin sehr dankbar um den Tipp!