Die Community zu .NET und Classic VB.
Menü

VB.NET-Tipp 0084: Drag'n Drop mit Filesystem-Items

 von 

Beschreibung

Für viele Anwendungen stellt es eine komfortable Eingabe dar, wenn Dateien oder Ordner vom Windows-Explorer auf die Anwendung gezogen werden können. Dieses Beispiel sammelt Filesystem-Items als Text in einer Listbox. Die Items können auch in Gegenrichtung in den Win-Explorer gezogen werden, mit der entsprechenden Kopier- bzw. Verschiebewirkung.

Also Vorsicht: Bei DragDropeffect.Move wird die gezogene Datei tatsächlich verschoben!

Schwierigkeitsgrad:

Schwierigkeitsgrad 2

Framework-Version(en):

.NET Framework 2.0, .NET Framework 3.0, .NET Framework 3.5

.NET-Version(en):

Visual Basic 2008

Download:

Download des Beispielprojektes [11,7 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 2008
' Option Strict:    An
' Option Infer:     An
'
' Referenzen: 
'  - System
'  - System.Core
'  - System.Drawing
'  - System.Windows.Forms
'  - System.Xml
'  - System.Xml.Linq
'
' Imports: 
'  - Microsoft.VisualBasic
'  - Microsoft.VisualBasic.ControlChars
'  - System
'  - System.Collections.Generic
'  - System.Linq
'  - System.Windows.Forms
'

' ##############################################################################
' ################################ frmMain.vb ##################################
' ##############################################################################
' Projekteinstellungen:
' Option Strict On
' Option Explicit On
' Option Infer On
' Imports System.Windows.Forms

Imports System.IO

Public Class frmMain

    Private _PrevMouse As New MouseEventArgs(0, 0, 0, 0, 0)

#Region "DragDrop empfangen"

    ' Im _DragOver muß durch Setzen von e.Effect festgelegt werden, welcher 
    '  DropEffect momentan unterstützt wird. Hier kommt nur .Copy in Frage, da 
    '  .Move die Source-Datei ja löschen würde. Bei Nicht-Festlegen gilt 
    '  DragDropEffects.None, und es kommt nie zum Dropping
    Private Sub ListBox1_DragOver(ByVal sender As Object, _
        ByVal e As DragEventArgs) Handles ListBox1.DragOver

        Dim DTO = TryCast(e.Data, DataObject)
        If DTO IsNot Nothing AndAlso DTO.ContainsFileDropList Then
            e.Effect = DragDropEffects.Copy
        End If
    End Sub

    ' Im _DragDrop wird nach dem schlußendlich gültigen Drop-Effect verfahren. 
    ' Dieses Beispiel braucht aber nicht auf verschiedene DropEffekte 
    ' abzuprüfen, da nur DragDropEffects.Copy möglich ist.
    Private Sub ListBox1_DragDrop(ByVal sender As Object, _
        ByVal e As DragEventArgs) Handles ListBox1.DragDrop

        Dim DTO = TryCast(e.Data, DataObject)
        ListBox1.Items.AddRange(DTO.GetFileDropList.Cast(Of String).ToArray)
    End Sub

#End Region 'DragDrop empfangen

#Region "DragDrop senden"
    ' Dragging wird gestartet, wenn ein Mousmove mit gehaltener Links-Taste 
    ' einem Links-Tasten-MouseDown folgt.
    Private Sub ListBox1_MouseDown(ByVal sender As Object, _
        ByVal e As MouseEventArgs) Handles ListBox1.MouseDown

        _PrevMouse = e
    End Sub

    Private Sub ListBox1_MouseMove(ByVal sender As Object, _
        ByVal e As MouseEventArgs) Handles ListBox1.MouseMove

        If _PrevMouse.Button = MouseButtons.Left AndAlso _
            e.Button = MouseButtons.Left Then

            Dim I = ListBox1.IndexFromPoint(_PrevMouse.Location)
            If I < 0 Then Return

            Dim SC As New System.Collections.Specialized.StringCollection
            Dim FullPath = ListBox1.Items(I).ToString
            SC.Add(FullPath)

            Dim DTO = New DataObject
            DTO.SetFileDropList(SC)

            ListBox1.AllowDrop = False
            Dim Result = ListBox1.DoDragDrop(DTO, _
                DragDropEffects.Copy Or DragDropEffects.Move)
            ListBox1.AllowDrop = True

            Select Case Result
                Case DragDropEffects.Copy
                    ' Nichts tun. Kopieren muß die Anwendung, auf die 
                    ' gedroppt wurde

                Case DragDropEffects.Move
                    ' Dieses funktioniert leider nicht.
                    ' Bei DropEffekt.Move bekomme ich DropEffekt.None zurück
                    ListBox1.Items.RemoveAt(I)

                Case DragDropEffects.None
                    ' Also gucken wir, ob das FilesystemItem gelöscht wurde
                    If (Not File.Exists(FullPath)) AndAlso _
                            (Not Directory.Exists(FullPath)) Then
                        ListBox1.Items.RemoveAt(I)
                    End If

            End Select
        End If
        _PrevMouse = e
    End Sub

#End Region 'DragDrop senden

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 4 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 General Bison am 06.01.2010 um 10:21

Aloha,
Es scheint zu stimmen, dass es nur in 3.5 richtig funzt.
Hier ist aber das fehlende glied zum Framework 2.0 ;)

Also dann viel spass an alle 2.0er =)

Private Sub TextBox1_DragDrop(ByVal sender As System.Object, ByVal e As DragEventArgs) Handles TextBox1.DragDrop
Dim oDroppedData As DataObject = CType(e.Data, DataObject)
Dim sFileList As System.Text.StringBuilder = New System.Text.StringBuilder()

For Each sFileName As String In oDroppedData.GetFileDropList()
sFileList.AppendLine(sFileName)
Next

MessageBox.Show(sFileList.ToString())
End Sub

Hab ich hier gefunden:
http://www.winboard.org/forum/programmierung/106925-vb-net-datei-per-drag-drop-textbox.html

Kommentar von am 09.12.2009 um 15:01

Folgender Code behebt das Problem mit dem "Case DragDropEfferts.Move":


Private Sub ListBox1_DragOver(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles ListBox1.DragOver

Dim DTO = TryCast(e.Data, DataObject)
If DTO IsNot Nothing AndAlso DTO.ContainsFileDropList Then
e.Effect = DragDropEffects.Copy or DragDropEffects.Move
End If
End Sub

Kommentar von Thau am 06.07.2009 um 19:26

Hi, bei mir funktioniert das Script super, aber nur wenn ich das .NET Framework 3.5 verwende da die vorigen Versionen scheinbar DTO.GetFileDropList.Cast nicht kennen.
Jetzt ist meine Frage, ob man den Drag and Drop auf Dateien beschränken kann, also so dass keine Ordner in die ListBox kommen. Geht das?

Kommentar von Schnickelfritz am 04.04.2009 um 01:52

Hui, da ist das bei einem Listview doch einfacher: da gibt es ein hübsches ItemDrag-Event. Also in etwa so:

Private Sub myListview_ItemDrag(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemDragEventArgs) Handles myListview.ItemDrag
Dim p As New System.Collections.Specialized.StringCollection
For Each lv As ListViewItem In myListview.SelectedItems
p.Add(lv.Tag.ToString)
Next
Dim dataObject As New DataObject()
dataObject.SetFileDropList(p)
lvM.AllowDrop = False
Dim r As DragDropEffects = myListview.DoDragDrop(dataObject, DragDropEffects.Copy Or DragDropEffects.Move)
lvM.AllowDrop = True
If r = DragDropEffects.Move Then
' klappt auch hier nicht
End If
End Sub