Jump to content
Xtreme .Net Talk

Drag&Drop files to a listbox hangs explorer and the program...


Recommended Posts

Posted

I have a form with one ListBox in it and use the code below. I have allowed drop to the listbox and plan to drop files to it (both folders and files). Files are added at once and folders are searched for more files and subfolders. But when I add a folder containing alot of files like the C-drive then both the program and explorer hang until all files are added.

I could prevent the program from hanging by adding Application.DoEvents() here and there but of course it has no effect on explorer. So how can I prevent explorer from hanging? I would like to drag&drop other folders to my app from explorer even when the previous folder had not yeat been fully processed.

 

   Private Sub ListBox1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox1.DragEnter

       ' Let's allow files to be dropped.
       If (e.Data.GetDataPresent(DataFormats.FileDrop)) Then
           e.Effect = DragDropEffects.Copy
       Else
           e.Effect = DragDropEffects.None
       End If

   End Sub

   Private Sub ListBox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox1.DragDrop

       ' Accept on files and folders.
       If (e.Data.GetDataPresent(DataFormats.FileDrop)) Then
           Dim Items() As Object = CType(e.Data.GetData(DataFormats.FileDrop), System.Object)
           Dim File As Object
           For Each File In Items
               ' Let's see if we are dealing with a file or a folder.
               If System.IO.File.Exists(File) Then
                   ' It's a file, so we add it to the listbox.
                   AddFile(File.ToString)
               ElseIf System.IO.Directory.Exists(File) Then
                   ' It's a folder, so we must search it for files.
                   FindFiles(File.ToString)
               End If
           Next
       End If

   End Sub

   Private Sub AddFile(ByVal FilePath As String)

       ' Simply add the file to the listbox.
       ListBox1.Items.Add(FilePath)

   End Sub

   Private Sub FindFiles(ByVal Directory As String)

       ' Find files in current folder.
       Try
           Dim Files As String() = System.IO.Directory.GetFiles(Directory, "*")
           Dim File As String
           For Each File In Files
               AddFile(File)
           Next
       Catch
       End Try

       ' Find subfolders in current folder and search them for files too.
       Try
           Dim Dirs As String() = System.IO.Directory.GetDirectories(Directory, "*")
           Dim Dir As String
           For Each Dir In Dirs
               FindFiles(Dir)
           Next
       Catch
       End Try

   End Sub

Posted

Trying...

 

I have been searching some info on threading and found a promising thread by Derek Stone but the links are dead!

 

Threading: Passing Parameters, Returning Values and Accessing Controls

http://www.xtremedotnettalk.com/showthread.php?t=70749&highlight=threading+instance

 

So does anyone of you know how to use threads with parameters and access controls from them? I think that could be the answer for my problem.

Posted

The ThreadPool object allows starting a separate thread with a parameter, using the QueueUserWorkItem method, the 2nd overload has two parameters: a WaitCallback delegate (the method to be called on a separate thread), and an object that will be passed to this method. This is a different solution than the one in that post, but there is a decent amount of explanation on msdn for it ;).

 

Search this forum for InvokeRequired for how to access user controls from a different thread. It should return plenty of results ;).

Nothing is as illusive as 'the last bug'.
Posted (edited)

I came up with this. Do you think there's any bad practise in the code?

 



Imports System.Threading

Public Class Form1




   Private Sub ListBox1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox1.DragEnter

       ' Let's allow files to be dropped.
       If (e.Data.GetDataPresent(DataFormats.FileDrop)) Then
           e.Effect = DragDropEffects.Copy
       Else
           e.Effect = DragDropEffects.None
       End If

   End Sub

   Private Sub ListBox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox1.DragDrop

       ' Accept files and folders.
       If (e.Data.GetDataPresent(DataFormats.FileDrop)) Then

           Dim Items() As Object = CType(e.Data.GetData(DataFormats.FileDrop), System.Object)

           Dim AddFilesClass As New AddFiles
           AddFilesClass.AddItems(Items, ListBox1)

       End If

   End Sub




End Class

Public Class AddFiles

   Private Shared ThreadCount As Integer

   Private Delegate Sub AddItemDelegate(ByVal FullPath As String, ByVal ListBox As ListBox)
   Private Delegate Sub StartAddItemsDelegate(ByVal Items() As Object, ByVal ListBox As ListBox)
   Private Delegate Sub EndAddItemsDelegate(ByVal ThreadName As String)

   Private Class AddFileArgs

       Public Items() As Object
       Public ListBox As ListBox
       Public StartDelegate As StartAddItemsDelegate
       Public EndDelegate As EndAddItemsDelegate

       Public Sub StartAdding()

           StartDelegate(Items, ListBox)
           EndDelegate(Thread.CurrentThread.Name)

       End Sub

   End Class

   Private Sub FilesAndFolders(ByVal Items() As Object, ByVal ListBox As ListBox)

       Dim File As Object
       For Each File In Items
           ' Let's see if we are dealing with a file or a folder.
           If System.IO.File.Exists(File) Then
               ' It's a file, so we add it to the listbox.
               If ListBox.InvokeRequired Then
                   ListBox.Invoke(New AddItemDelegate(AddressOf AddFile), New Object() {File.ToString, ListBox})
               Else
                   Me.AddFile(File.ToString, ListBox)
               End If
           ElseIf System.IO.Directory.Exists(File) Then
               ' It's a folder, so we must search it for files.
               AddDirectory(File.ToString, ListBox)
           End If
       Next

   End Sub

   Private Sub AddFile(ByVal FilePath As String, ByVal ListBox As ListBox)

       ' Simply add the file to the listbox.
       ListBox.Items.Add(FilePath)

   End Sub

   Private Sub AddDirectory(ByVal Directory As String, ByVal ListBox As ListBox)

       ' Find files in current folder.
       Try
           Dim Files As String() = System.IO.Directory.GetFiles(Directory, "*")
           Dim File As String
           For Each File In Files
               ' Add the file
               If ListBox.InvokeRequired Then
                   ListBox.Invoke(New AddItemDelegate(AddressOf AddFile), New Object() {File, ListBox})
               Else
                   Me.AddFile(File, ListBox)
               End If
           Next
       Catch
       End Try

       ' Find subfolders in current folder and search them for files too.
       Try
           Dim Dirs As String() = System.IO.Directory.GetDirectories(Directory, "*")
           Dim Dir As String
           For Each Dir In Dirs
               AddDirectory(Dir, ListBox)
           Next
       Catch
       End Try

   End Sub

   Private Sub Done(ByVal threadName As String)

       'If ListBox1.InvokeRequired Then
       '    Debug.Print("Done is executing on the launched thread.")
       'Else
       '    Debug.Print("Done is executing on the main thread.")
       'End If
       Debug.Print(threadName & " finished.")

   End Sub

   ' *** It all starts here ****
   Public Sub AddItems(ByVal Items() As Object, ByVal ListBox As ListBox)

       Dim ca As New AddFiles.AddFileArgs
       ca.Items = Items
       ca.ListBox = ListBox
       ca.StartDelegate = AddressOf FilesAndFolders
       ca.EndDelegate = AddressOf Done

       Dim t As New Thread(AddressOf ca.StartAdding)
       ThreadCount += 1
       t.Name = "Thread " & ThreadCount
       Debug.Print(t.Name & " started.")
       t.Priority = ThreadPriority.BelowNormal
       t.IsBackground = True
       t.Start()

   End Sub

End Class




Edited by JumpyNET

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...