|
-
Jun 30th, 2009, 10:36 AM
#1
Thread Starter
Fanatic Member
[RESOLVED] Multiple file move via DragAndDrop
I'm going to try this again since last time I asked (a long time ago now) I didn't get many responses. Maybe someone who knew didn't see my post or maybe someone new is around who might know.
I want to add a file drag and drop feature to my program that allows people to drag files onto my form and when the files are released on a path (that is stored in a listbox) it moves/copies the files to that folder.
I have all that working but what my issue is that each file has to be handled individually.
Now, Windows can move multiple files all in a single group; it calculates time till completion based on the cumulative size of all the files and shows a progress bar in that way.
Currently, all I can do is either let it happen, or show a progress bar for each file.
Does anyone know how to get files in an array of files to drop to display like Windows does with multiple files when moving or copying.
Visual Studio 2010 Professional | .NET Framework 4.0 | Windows 7
SERYSOFT.COM :: SysPad - Folder Management Program - Please comment HERE if you find this program useful, have ideas, or know of any bugs.
[Very useful for IT/DP departments where many folders are consistently accessed. Also contains a scratchpad window for quick access to notes.]
[.NET and MySQL Quick Guide]
-
Jun 30th, 2009, 01:08 PM
#2
Re: Multiple file move via DragAndDrop
You're not having problems getting your form to process multiple dragged files right? What you want is an accurate multifile copy progress bar. In that case, you'll want manual copying. Use filestreams with a progressbar. Something like this:
Code:
Public Class Form1
Friend WithEvents bgCopy As New System.ComponentModel.BackgroundWorker With {.WorkerReportsProgress = True}
Private Structure copyDetails
Dim moveFiles As Boolean
Dim destination As String
Dim filesToCopy() As IO.FileInfo
End Structure
Private Sub Button1_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs _
) Handles Button1.Click
Dim files(ListBox1.Items.Count - 1) As IO.FileInfo
Dim total As Long = 0
For i As Integer = 0 To ListBox1.Items.Count - 1
files(i) = New IO.FileInfo(ListBox1.Items(i).ToString())
total += files(i).Length
Next
ProgressBar1.Maximum = total
ProgressBar1.Step = 4096
bgCopy.RunWorkerAsync( _
New copyDetails() With { _
.destination = TextBox1.Text, _
.filesToCopy = files, _
.moveFiles = CheckBox1.Checked _
} _
)
End Sub
Private Sub bgCopy_DoWork( _
ByVal sender As System.Object, _
ByVal e As System.ComponentModel.DoWorkEventArgs _
) Handles bgCopy.DoWork
Dim copyArgs As copyDetails = DirectCast(e.Argument, copyDetails)
Dim bgWorker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
For Each f As IO.FileInfo In copyArgs.filesToCopy
Using fsIn As New IO.FileStream( _
f.FullName, IO.FileMode.Open, IO.FileAccess.Read _
)
Using fsOut As New IO.FileStream( _
f.FullName.Replace(f.DirectoryName, copyArgs.destination), IO.FileMode.Create, IO.FileAccess.Write _
)
Dim offset As Long = 0
Dim total As Long = fsIn.Length
Dim toCopy(4096) As Byte
While offset + 4096 < total
fsIn.Read(toCopy, 0, toCopy.Length)
fsOut.Write(toCopy, 0, toCopy.Length)
bgWorker.ReportProgress(0)
offset += 4096
End While
fsIn.Read(toCopy, 0, toCopy.Length)
fsOut.Write(toCopy, 0, CInt(total - offset))
bgWorker.ReportProgress(0)
fsIn.Flush()
fsOut.Flush()
End Using
End Using
If copyArgs.moveFiles Then _
f.Delete()
Next
End Sub
Private Sub bgCopy_ProgressChanged( _
ByVal sender As System.Object, _
ByVal e As System.ComponentModel.ProgressChangedEventArgs _
) Handles bgCopy.ProgressChanged
If ProgressBar1.Value < ProgressBar1.Maximum - ProgressBar1.Step Then
ProgressBar1.PerformStep()
Else
ProgressBar1.Value = ProgressBar1.Maximum
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Using f As New OpenFileDialog() With {.Multiselect = True}
f.ShowDialog()
ListBox1.Items.AddRange(f.FileNames)
End Using
End Sub
End Class
This may not be the most efficient method, we'll have to get input from others. I used a background worker for obvious reasons.
Last edited by MaximilianMayrhofer; Jun 30th, 2009 at 01:14 PM.
-
Jun 30th, 2009, 02:23 PM
#3
Thread Starter
Fanatic Member
Re: Multiple file move via DragAndDrop
Yeah. No problems with actually moving the files. Just looking for a way to contain all the files and make it look like Windows is handling them as a whole, like Windows does.
I just wasn't sure if there was a way to do it or if I'd have to build my own setup.
I'll probably fool around with this later when I get home and see how it works.
Thanks for the input
Visual Studio 2010 Professional | .NET Framework 4.0 | Windows 7
SERYSOFT.COM :: SysPad - Folder Management Program - Please comment HERE if you find this program useful, have ideas, or know of any bugs.
[Very useful for IT/DP departments where many folders are consistently accessed. Also contains a scratchpad window for quick access to notes.]
[.NET and MySQL Quick Guide]
-
Jul 6th, 2009, 11:54 PM
#4
Thread Starter
Fanatic Member
Re: Multiple file move via DragAndDrop
OK, so here's my modifications.
Your base functions still exist as you wrote them, but I had to modify what was in the Button1 to try to get it to work with my DragDrop event.
I added: "Friend WithEvents bgCopy As New System.ComponentModel.BackgroundWorker With {.WorkerReportsProgress = True}" and got the following error:
Error 1 'bgCopy' is already declared as 'Friend WithEvents bgCopy As System.ComponentModel.BackgroundWorker' in this class. D:\_prog\SysPad\SysPad\frmFolderPad.vb 19 23 SysPad
And as far as running the code, nothing happens when I drop some files on the list item.
Code:
Private Sub folderList_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles folderList.DragDrop
If e.Data.GetDataPresent("FileNameW", True) Then
Dim paths As System.Array = CType(e.Data.GetData(DataFormats.FileDrop), System.Array)
Dim strDestPath As String = txtPath.Text
Dim blnMove As Boolean
Dim totalFiles As Integer = paths.Length
If (e.KeyState And CtrlMask) = CtrlMask Then
blnMove = False
Else
blnMove = True
End If
Dim files(totalFiles) As IO.FileInfo
Dim total As Long = 0
For i As Integer = 0 To totalFiles
files(i) = New IO.FileInfo(paths(i).ToString)
total += files(i).Length
Next
ProgressBar1.Maximum = totalFiles
ProgressBar1.Step = 4096
bgCopy.RunWorkerAsync(New copyDetails() With {.destination = strDestPath & "\", .filesToCopy = files, .moveFiles = blnMove})
End If
End Sub
Last edited by Seraph; Jul 7th, 2009 at 07:49 AM.
Visual Studio 2010 Professional | .NET Framework 4.0 | Windows 7
SERYSOFT.COM :: SysPad - Folder Management Program - Please comment HERE if you find this program useful, have ideas, or know of any bugs.
[Very useful for IT/DP departments where many folders are consistently accessed. Also contains a scratchpad window for quick access to notes.]
[.NET and MySQL Quick Guide]
-
Jul 7th, 2009, 10:25 AM
#5
Thread Starter
Fanatic Member
Re: Multiple file move via DragAndDrop
/bump
If anyone else can makes sense of this and maybe provide some insight, that would be greatly appreciated.
This feature has yet to make it into a version of my program, but would really like to try to implement it in this next update.
I tried awhile back, and got the basic concept working, but didn't work like I'm trying to accomplish here.
Visual Studio 2010 Professional | .NET Framework 4.0 | Windows 7
SERYSOFT.COM :: SysPad - Folder Management Program - Please comment HERE if you find this program useful, have ideas, or know of any bugs.
[Very useful for IT/DP departments where many folders are consistently accessed. Also contains a scratchpad window for quick access to notes.]
[.NET and MySQL Quick Guide]
-
Jul 7th, 2009, 01:51 PM
#6
Re: Multiple file move via DragAndDrop
It's not working because your first if statement is returning false. What is "FileNameW"?
-
Jul 7th, 2009, 01:54 PM
#7
Thread Starter
Fanatic Member
Re: Multiple file move via DragAndDrop
It has something to do with GetDataPresent directly as in, you could put "FileName" and it would return something different.
Not sure what you call it.
Maybe I deleted some other code; though I thought I still had it all, just commented out till I needed it again.
Visual Studio 2010 Professional | .NET Framework 4.0 | Windows 7
SERYSOFT.COM :: SysPad - Folder Management Program - Please comment HERE if you find this program useful, have ideas, or know of any bugs.
[Very useful for IT/DP departments where many folders are consistently accessed. Also contains a scratchpad window for quick access to notes.]
[.NET and MySQL Quick Guide]
-
Jul 7th, 2009, 02:38 PM
#8
Thread Starter
Fanatic Member
Re: Multiple file move via DragAndDrop
.fileToCopy is just suppsoed to be an array of file paths right?
I know that files is populated with my paths because I ran a MessageBox outputting whatever was in the files(i) index after each index was given its value.
If files is simply an array of string paths, then it should be being passed fine to the bgCopy.
Visual Studio 2010 Professional | .NET Framework 4.0 | Windows 7
SERYSOFT.COM :: SysPad - Folder Management Program - Please comment HERE if you find this program useful, have ideas, or know of any bugs.
[Very useful for IT/DP departments where many folders are consistently accessed. Also contains a scratchpad window for quick access to notes.]
[.NET and MySQL Quick Guide]
-
Jul 7th, 2009, 05:17 PM
#9
Re: Multiple file move via DragAndDrop
Put a breakpoint anywhere in that code and see if it gets tripped, then you'll know if the code is even executing at all.
-
Jul 7th, 2009, 08:20 PM
#10
Thread Starter
Fanatic Member
Re: Multiple file move via DragAndDrop
Well, no MessageBoxes (I prefer message boxes) displayed from within the DoWork.
I even took the If statement out and the RunWorkerAsync still didn't trigger.
Visual Studio 2010 Professional | .NET Framework 4.0 | Windows 7
SERYSOFT.COM :: SysPad - Folder Management Program - Please comment HERE if you find this program useful, have ideas, or know of any bugs.
[Very useful for IT/DP departments where many folders are consistently accessed. Also contains a scratchpad window for quick access to notes.]
[.NET and MySQL Quick Guide]
-
Jul 7th, 2009, 10:10 PM
#11
Re: Multiple file move via DragAndDrop
E.g.
Code:
Public Class Form1
Private Sub Form1_DragEnter(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles Me.DragEnter
If Me.CanCopyFiles(e) Then
e.Effect = DragDropEffects.Copy
End If
End Sub
Private Sub Form1_DragDrop(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles Me.DragDrop
If Me.CanCopyFiles(e) Then
Me.BackgroundWorker1.RunWorkerAsync(DirectCast(e.Data.GetData("FileDrop"), String()))
End If
End Sub
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, _
ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim filePaths = DirectCast(e.Argument, String())
Dim totalSize = 0L
For Each filePath In filePaths
totalSize += New IO.FileInfo(filePath).Length
Next
Dim destinationPath = IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.MyDocuments, "Test")
If Not IO.Directory.Exists(destinationPath) Then
IO.Directory.CreateDirectory(destinationPath)
End If
Const BUFFER_SIZE As Integer = 4096
Dim buffer(BUFFER_SIZE - 1) As Byte
Dim bytesRead As Integer
Dim bytesCopied = 0L
For Each filePath In filePaths
Using source = IO.File.Open(filePath, _
IO.FileMode.Open)
Using destination = IO.File.Open(IO.Path.Combine(destinationPath, _
IO.Path.GetFileName(filePath)), _
IO.FileMode.Create)
Do
bytesRead = source.Read(buffer, 0, BUFFER_SIZE)
If bytesRead > 0 Then
destination.Write(buffer, 0, bytesRead)
bytesCopied += bytesRead
Me.BackgroundWorker1.ReportProgress(Me.GetPercentage(bytesCopied, _
totalSize), _
filePath)
End If
Loop Until bytesRead < BUFFER_SIZE
End Using
End Using
Next
End Sub
Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, _
ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Me.Label1.Text = CStr(e.UserState)
Me.ProgressBar1.Value = e.ProgressPercentage
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, _
ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
MessageBox.Show("Copy complete")
End Sub
Private Function CanCopyFiles(ByVal e As DragEventArgs) As Boolean
Return e.Data.GetDataPresent("FileDrop") AndAlso _
(e.AllowedEffect And DragDropEffects.Copy) = DragDropEffects.Copy
End Function
Private Function GetPercentage(ByVal value As Long, ByVal total As Long) As Integer
Return CInt(value / total * 100L)
End Function
End Class
Assumes that the AllowDrop property of the form and the WorkerReportsProgress property of the BackgroundWorker are both True. Note that the Maximum of the ProgressBar should also be left at the default of 100 as we are reporting a percentage of data copied, not an absolute number of bytes.
Finally, not that I use "FileDrop" as the data format. "FileName" and "FileNameW" can only get one file path while "FileDrop" can get multiple.
-
Jul 8th, 2009, 12:12 AM
#12
Thread Starter
Fanatic Member
Re: Multiple file move via DragAndDrop
AllowDrop is actually set on the listbox folderList (for my case)
WorkerReportsProgress was not True (is now)
FileNameW can get more than one.
I ran it through a loop. All files that were dropped were listed with their paths.
Visual Studio 2010 Professional | .NET Framework 4.0 | Windows 7
SERYSOFT.COM :: SysPad - Folder Management Program - Please comment HERE if you find this program useful, have ideas, or know of any bugs.
[Very useful for IT/DP departments where many folders are consistently accessed. Also contains a scratchpad window for quick access to notes.]
[.NET and MySQL Quick Guide]
-
Jul 8th, 2009, 12:16 AM
#13
Thread Starter
Fanatic Member
Re: Multiple file move via DragAndDrop
Dunno if those were supposed to help, but nothing is happening still.
No messageboxes.
Visual Studio 2010 Professional | .NET Framework 4.0 | Windows 7
SERYSOFT.COM :: SysPad - Folder Management Program - Please comment HERE if you find this program useful, have ideas, or know of any bugs.
[Very useful for IT/DP departments where many folders are consistently accessed. Also contains a scratchpad window for quick access to notes.]
[.NET and MySQL Quick Guide]
-
Jul 8th, 2009, 12:23 AM
#14
Re: Multiple file move via DragAndDrop
My code copies files as is. Have you tried it? The idea is that you would create a new project and then run my code to see how it works. I would think that you should be able to adapt that to your own needs. It's an example that demonstrates the principle and you can then implement the principle as appropriate in your own project.
-
Jul 8th, 2009, 12:24 AM
#15
Thread Starter
Fanatic Member
Re: Multiple file move via DragAndDrop
oh..hah...lol...i was thinkin u were commenting on his code..sorry...wanst paying attention
Visual Studio 2010 Professional | .NET Framework 4.0 | Windows 7
SERYSOFT.COM :: SysPad - Folder Management Program - Please comment HERE if you find this program useful, have ideas, or know of any bugs.
[Very useful for IT/DP departments where many folders are consistently accessed. Also contains a scratchpad window for quick access to notes.]
[.NET and MySQL Quick Guide]
-
Jul 8th, 2009, 10:33 AM
#16
Thread Starter
Fanatic Member
Re: Multiple file move via DragAndDrop
Well, that worked perfectly fine.
However, folders won't move.
The program crashes with an error stating the "file" can't be found.
Do folder's have to be handled differently?
Visual Studio 2010 Professional | .NET Framework 4.0 | Windows 7
SERYSOFT.COM :: SysPad - Folder Management Program - Please comment HERE if you find this program useful, have ideas, or know of any bugs.
[Very useful for IT/DP departments where many folders are consistently accessed. Also contains a scratchpad window for quick access to notes.]
[.NET and MySQL Quick Guide]
-
Jul 8th, 2009, 10:50 PM
#17
Re: Multiple file move via DragAndDrop
Folders aren't files so yes, they have to be handled differently. You can call File.Exists and, if that's False, Directory.Exists to decide whether the path refers to a file or folder. You can then use the File class or the Directory class to process it accordingly.
-
Jul 8th, 2009, 10:58 PM
#18
Thread Starter
Fanatic Member
Re: Multiple file move via DragAndDrop
Visual Studio 2010 Professional | .NET Framework 4.0 | Windows 7
SERYSOFT.COM :: SysPad - Folder Management Program - Please comment HERE if you find this program useful, have ideas, or know of any bugs.
[Very useful for IT/DP departments where many folders are consistently accessed. Also contains a scratchpad window for quick access to notes.]
[.NET and MySQL Quick Guide]
-
Jul 9th, 2009, 08:46 PM
#19
Thread Starter
Fanatic Member
Re: Multiple file move via DragAndDrop
well...im looking at this, and I'm not exactly sure what to do...
I mean, once I determine if it's a folder...how do I determine the size of what's in it.
I mean, I guess I can move it with .Move, but it seems to be able to determine exactly what is in there for the total size for the progress bar, i need to go through each folder and determine all of the files that are in them.
and what about moving a folder. If I use .Move, will it move the progressbar properly while the folder is being moved?
Visual Studio 2010 Professional | .NET Framework 4.0 | Windows 7
SERYSOFT.COM :: SysPad - Folder Management Program - Please comment HERE if you find this program useful, have ideas, or know of any bugs.
[Very useful for IT/DP departments where many folders are consistently accessed. Also contains a scratchpad window for quick access to notes.]
[.NET and MySQL Quick Guide]
-
Jul 9th, 2009, 08:59 PM
#20
Re: Multiple file move via DragAndDrop
To determine the size of a folder you simply have to sum the sizes of the files it contains. Try viewing the properties of a large folder in Windows Explorer and you'll see Windows does the same.
How exactly would calling Move update the ProgressBar? We can't even call File.Move so we can hardly call Directory.Move. To move a folder you'll have to move each file it contains in the same way as you already are moving files. To move a folder would involve creating the new folder, copying the files, deleting the old files and deleting the old folder.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|