Page 1 of 1

Drag and Drop Files Drag and drop files and folders to/from windows, other apps Rate Topic: ***** 1 Votes

#1 dzone41  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 46
  • View blog
  • Posts: 216
  • Joined: 21-August 09

Posted 16 October 2009 - 03:07 PM

Drag and Drop.....beyond text.

I've been wanting to write this tutorial for a while,
the dragging and dropping of files took me a long
time to get right, all the help I could find on drag and drop
concentrated on text and images.
So......here goes my first DIC tut.

The ListView boxes in the example are as basic as possible.
I have put very little code into them in order to keep
the focus on dragdrop. Therefore, they will not show the
changes in the file system.

The first step of course is to enable dragdrop on the controls.
In the properties for all controls that you want to allow
dropping into, set "AllowDrop" property to "True".

In this example I have two ListViews that you populate
with files and folders from a location
on your computer.

We will be able:
1. drag from one ListView to the other
2. drag into windows explorer
3. drag from windows explorer into our application.

In the example I have placed two class scope variables
at the top.
The first thing to remember and account for:
To move or copy files or folders by dragdrop, you need paths;
File.Move(oldPath, newPath)
Directory.Copy(oldPath, NewPath)
So the "class variables", as I will refer to them (since
there are only two), will hold the path information for the
ListViews.

First the drag:


Private Sub OnMouseDrag(ByVal sender As Object, _
ByVal m As System.Windows.Forms.ItemDragEventArgs) _
Handles ListView1.ItemDrag, ListView2.ItemDrag

	'The strings should explain themselves, they will be
	' used to recreate full file and folder paths
	Dim strPath, strName, strFullPath As String

	'Determine which ListView is being Dragged From
	'so we can get the correct parent path from the 
	'class variable
	Dim LView As ListView = sender
	If LView Is ListView1 Then
		strPath = LView1Path
	ElseIf LView Is ListView2 Then
		strPath = LView2Path
	Else
		Exit Sub
	End If

	'Put the dragged ListView Item or Items into a variable
	Dim items As ListView.SelectedListViewItemCollection = _
	LView.SelectedItems

	'Create a string list of File and Folder Paths
	Dim DropList As New StringCollection

	'Iterate through the dragged (selected) items
	'Since the item is selected and a item is being
	'dragged....which triggered this event, we will
	'assumed all selected items want to be dragged

	For Each item As ListViewItem In items
		strName = item.Text
		strFullPath = strPath & "\" & strName

		'...."FileInfo".... Another critical type

		Dim FtoDrop As FileInfo = New FileInfo(strFullPath)

		 DropList...StringCollection

		DropList.Add(strFullPath)
	Next

	' The "DataObject"...critical to the operation
	Dim DragPaths As New DataObject()

	'Now we use the ".SetFileDropList()" Method to set the 
	'File drop list into the "DataObject"
	DragPaths.SetFileDropList(DropList)

	'The standard dragdrop method. If you do not need to 
	'limit dragdrop effects for a reason, then set to "All"

	DoDragDrop(DragPaths, DragDropEffects.All)


End Sub




The Bulk of the code is dealing with the path strings.
This is where major differences will occur in other applications
since there are so many ways of handling and representing files.
But before we get to the dragdrop stuff....we just have a path to
a file or directory.

Then we put all of the paths into an array, collection, arraylist
whatever container you would prefer. Must be "String" data.

Put the paths into a "DataObject". DragPaths is our DataObject
DragPaths.SetFileDropList(DropList)

Then finally:
DoDragDrop(DragPaths, DragDropEffects.All)

DragDropEffects.All will allow the control recieving the
dragged items to do whatever it wants with them...Move, copy,
link.


So that that part is easy huh?
Guess what???? Now, with this code alone (dragdrop code)
you can drag an file or folder from your application into
Windows Explorer!!
(remember, the ListViews do not update themselves, so you will
not be able to see the change in the ListView.)
Go to the folder in Windows and watch the file move when you
move it out of your application.

So now, we want to recieve the dropped file or folder.


Private Sub LView_DragEnter(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DragEventArgs) _
Handles ListView1.DragOver, ListView2.DragOver

	'When you drag over a control, it evaluates the object
	'being dragged to see if it can accept it.
	'Here, the data must be in data format "FileDrop"
	If (e.Data.GetDataPresent(DataFormats.FileDrop)) Then

		'If "move" is allowed by the origin, then the file
		'will be moved. We set our ListViews to "All".
		'So move is allowed.
		'At this point, more conditions can tested to
		'determine what action to take i.e. move, copy...
		e.Effect = DragDropEffects.Move
	Else
		e.Effect = DragDropEffects.None
	End If

End Sub




Now, our ListView is ready to recieve a drop event:


Private Sub LView_ItemDropped(ByVal sender As Object, _
	ByVal e As System.Windows.Forms.DragEventArgs) _
	Handles ListView1.DragDrop, ListView2.DragDrop

   'Now add the final routine...the dragdrop event
   'To copy or move a file, we need two Paths: 
   'The current path and destination path.
	'The current path is obtained from the file to be dropped
	'The destination path is obtained from the class
	'   variables set up for the ListViews

	'This extracts the collection of path strings from the
	'DataObject
	Dim Paths As String() = _
	DirectCast(e.Data.GetData(DataFormats.FileDrop), _
	String())

	'To get the destination path, find out which ListView
	'called this Event, then use the appropiate class variable
	Dim strDestination As String
	Dim LView As ListView = sender
	If LView Is ListView1 Then
		strDestination = LView1Path
	ElseIf LView Is ListView2 Then
		strDestination = LView2Path
	Else
		Exit Sub
	End If

	'iterate through the path strings
	For Each path As String In Paths

		'The following "If" block will determine if the 
		'path is a file or directory
		If File.Exists(path) Then

			'This same method was used to populate 
			'the ListView
			Dim _file As FileInfo = New FileInfo(path)
			Dim _fileName As String = _file.Name

			'Create a path from the peices
			Dim newPath As String = _
				strDestination & "\" & _fileName
			Try

				'Move the file!!
				File.Move(path, newPath)

			Catch ex As Exception
				' This is not about error handlers so we 
				' will just ignore the error and keep on
				' going
				Continue For
			End Try
			'If it isn't a file, then it should be a 
			'directory
		ElseIf Directory.Exists(path) Then

			Dim dir As DirectoryInfo = _
				New DirectoryInfo(path)
			Dim dirName As String = dir.Name
			Dim newPath As String = _
				strDestination & "\" & dirName

			Try
				Directory.Move(path, newPath)
			Catch ex As Exception
				Continue For
			End Try
		End If

	Next
End Sub




Remember what I said earlier...it's all about paths...
We need to get some paths!!

The container we put the paths into must be able to hold an
undetermined number of items...even if we know for sure only
one item is being dropped.

Dim Paths As String() = _
DirectCast(e.Data.GetData(DataFormats.FileDrop), String())

We now have the paths!!!....That's it!!!
The rest of the code is determining what to do with them.
We put them into a collection....now take them out of
a collection, manipulate the string data to create the needed
paths, every thing we have already done...but in reverse.

Then the final Action...move, copy, link.....

Attached File(s)



Is This A Good Question/Topic? 1
  • +

Replies To: Drag and Drop Files

#2 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2271
  • View blog
  • Posts: 9,499
  • Joined: 29-May 08

Posted 17 October 2009 - 02:34 PM

That was a good tutorial, suggestions to improve your next one.
Give the controls meaningful names rather than ListView1 change it Departure_ListView
Don't simply ignore errors.

Improvements to Sub PopulateListView to enable refreshing listviews to reflect the changes.

	Dim files() As FileInfo = di.GetFiles()
	LView.Items.Clear()



  PopulateListView(Me.ListView1, LView1Path)
  PopulateListView(Me.ListView2, LView2Path)
   End Sub


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1