I'm sure others have posted about this topic before but I'm sure another won't hurt. I'll post various examples of drag & drop within the same control, between controls and between applications.
If you're interested in performing drag & drop operations in WinForms then I suggest that you read this and this at least.
I'll start with moving items between two ListBoxes, which is relatively simple.
1. Create a new WinForms application project.
2. Add two ListBoxes to the form.
3. Add the following code:
Code:
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As EventArgs) Handles MyBase.Load
'Allow data to be dropped on both ListBoxes.
Me.ListBox1.AllowDrop = True
Me.ListBox2.AllowDrop = True
'Populate the ListBoxes.
Me.ListBox1.Items.AddRange(New String() {"List 1, Item 1", _
"List 1, Item 2", _
"List 1, Item 3", _
"List 1, Item 4", _
"List 1, Item 5"})
Me.ListBox2.Items.AddRange(New String() {"List 2, Item 1", _
"List 2, Item 2", _
"List 2, Item 3", _
"List 2, Item 4", _
"List 2, Item 5"})
End Sub
Private Sub ListBox_MouseDown(ByVal sender As Object, _
ByVal e As MouseEventArgs) Handles ListBox1.MouseDown, _
ListBox2.MouseDown
Dim source As ListBox = DirectCast(sender, ListBox)
For index As Integer = 0 To source.Items.Count - 1
'Test whether the mouse location is within an item
If source.GetItemRectangle(index).Contains(e.Location) Then
'The mouse was depressed on an item so allow a move operation.
source.DoDragDrop(source, DragDropEffects.Move)
Exit For
End If
Next
End Sub
Private Sub ListBox_DragEnter(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles ListBox1.DragEnter, _
ListBox2.DragEnter
Dim source As ListBox = DirectCast(sender, ListBox)
If e.Data.GetDataPresent("System.Windows.Forms.ListBox", False) AndAlso _
e.Data.GetData("System.Windows.Forms.ListBox", False) IsNot source Then
'The data being dragged is a ListBox but not the one that was just entered.
e.Effect = DragDropEffects.Move
End If
End Sub
Private Sub ListBox_DragDrop(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles ListBox1.DragDrop, _
ListBox2.DragDrop
Dim source As ListBox = DirectCast(sender, ListBox)
If e.Data.GetDataPresent("System.Windows.Forms.ListBox", False) Then
'Get the ListBox that the data was dragged from.
Dim data As ListBox = DirectCast(e.Data.GetData("System.Windows.Forms.ListBox", _
False), _
ListBox)
'Make sure we aren't trying to drag from and drop to the same control.
If data IsNot source Then
'Get the item that was dragged.
Dim item As Object = data.SelectedItem
'Remove the item from its original location.
data.Items.Remove(item)
'Get the current mouse location relative to the control being dropped on.
Dim location As Point = source.PointToClient(New Point(e.X, e.Y))
Dim dropIndex As Integer = -1
'Find the item over which the mouse was released.
For index As Integer = 0 To source.Items.Count - 1
If source.GetItemRectangle(index).Contains(location) Then
dropIndex = index
Exit For
End If
Next
If dropIndex = -1 Then
'The mouse was not released over an item so add the new item to the end.
source.Items.Add(item)
Else
'Insert the new item above the item it was dropped on.
source.Items.Insert(dropIndex, item)
End If
End If
End If
End Sub
4. Run the project and start dragging and dropping.
I'll refine this example and add more over time. If there's anything you specifically want to see then post a request and I'll see if I can get to it.
As requested in post #34, I have reworked the above example to allow multiple items to be dragged and dropped.
This example demonstrates dragging one or more files from Windows Explorer, or some other application that supports dragging files, into a ListView.
1. Create a new WinForms project.
2. Add a ListView and an ImageList to the form.
3. Add the following code:
Code:
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As EventArgs) Handles MyBase.Load
'Initialise the ListView.
Me.ListView1.AllowDrop = True
Me.ListView1.Columns.Add("File name")
Me.ListView1.Dock = DockStyle.Fill
Me.ListView1.SmallImageList = Me.ImageList1
Me.ListView1.View = View.Details
End Sub
Private Sub ListView1_DragEnter(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles ListView1.DragEnter
If e.Data.GetDataPresent("FileDrop") AndAlso _
(e.AllowedEffect And DragDropEffects.Copy) = DragDropEffects.Copy Then
'A file list is being dragged and it can be copied so provide feedback to the user.
e.Effect = DragDropEffects.Copy
End If
End Sub
Private Sub ListView1_DragDrop(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles ListView1.DragDrop
'The data can only be dropped if it is a file list and it can be copied.
If e.Data.GetDataPresent("FileDrop") AndAlso _
(e.AllowedEffect And DragDropEffects.Copy) = DragDropEffects.Copy Then
'Get the data.
Dim filePaths As String() = DirectCast(e.Data.GetData("FileDrop"), _
String())
Dim upperBound As Integer = filePaths.GetUpperBound(0)
Dim items(upperBound) As ListViewItem
Dim filePath As String
'For each file in the list, create an item, complete with icon.
For index As Integer = 0 To upperBound
filePath = filePaths(index)
If Not Me.ImageList1.Images.Keys.Contains(filePath) Then
'This is the first time this file has been added so add its icon too.
Me.ImageList1.Images.Add(filePath, _
Icon.ExtractAssociatedIcon(filePath))
End If
items(index) = New ListViewItem(filePath, filePath)
Next
'Add the items to the ListView.
Me.ListView1.Items.AddRange(items)
End If
End Sub
4. Run the project.
5. Select one or more files in Windows Explorer and drag them onto your form.
Tada! Note that, as before, I've done some setup of design time elements that you'd normally do in the designer. It was easier to do it in code than to explain though, for the purpose of this example.
Last edited by jmcilhinney; Nov 12th, 2008 at 01:21 AM.
I'm going to use that last example as a basis for showing you how to build up drag & drop code. I can hear people now saying "But how would I know to use the FileDrop format and how would I know that it returns a String array". Well, I'm going to show you how you work that out.
First up, you have to make sure that your control is a drop target, so set its AllowDrop property to True. Next you need to test what formats the data being dragged is available in. To do that you use the GetFormats method. GetFormats returns a String array, so you can loop through it to see what formats you can get the data in:
vb.net Code:
Private Sub ListView1_DragEnter(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles ListView1.DragEnter
For Each format As String In e.Data.GetFormats()
MessageBox.Show(format)
Next
End Sub
Drag your data onto the control and it will start popping up messages for each format. You might prefer to use Console.WriteLine and view the list in the Output window as it's less intrusive.
You now need to determine what .NET object will be created if you get the data in each of those formats and then decide which of those is most useful to you. To do that, you first need to get the data in each of those formats and then test it's type:
vb.net Code:
Private Sub ListView1_DragEnter(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles ListView1.DragEnter
You can then examine each of those objects based on its .NET type. Those that return a MemoryStream are going to be a little harder to interpret, but the String arrays are going to be easy to examine, so let's start with them:
vb.net Code:
Private Sub ListView1_DragEnter(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles ListView1.DragEnter
So, having done that by dragging multiple files you will now know that the FileName format returns the path of the first file in DOS-compatible format, the FileNameW format returns the full path of the first file and the FileDrop format returns the full paths of all the files. In this case that's as far as we need to go because the full paths of all files is exactly what we need. We now know that we need to test for the FileDrop format, which we do with GetDataPresent, and then get the data in that format, which we do with GetData.
That's basically how you should approach all drag & drop operations.
Last edited by jmcilhinney; Apr 29th, 2010 at 07:50 PM.
1. Create a new Windows Forms project.
2. Add a ListBox to the form.
3. Add the following code:
Code:
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As EventArgs) Handles MyBase.Load
'Initialise the ListBox.
Me.ListBox1.AllowDrop = True
Me.ListBox1.Items.AddRange(New String() {"Item 1", _
"Item 2", _
"Item 3", _
"Item 4", _
"Item 5"})
End Sub
Private Sub ListBox1_MouseDown(ByVal sender As Object, _
ByVal e As MouseEventArgs) Handles ListBox1.MouseDown
'Test whether the mouse is over an item.
If Me.GetItemIndexAtPoint(e.Location) <> -1 Then
'The mouse is over an item so start dragging.
Me.ListBox1.DoDragDrop(Me.ListBox1, DragDropEffects.Move)
End If
End Sub
Private Sub ListBox1_DragEnter(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox1.DragEnter, _
ListBox1.DragOver
'Test whether the data being dragged is the ListBox itself.
If e.Data.GetDataPresent("System.Windows.Forms.ListBox") AndAlso _
e.Data.GetData("System.Windows.Forms.ListBox") Is Me.ListBox1 Then
'Get the location of the mouse relative to the ListBox.
Dim mouseLocation As Point = Me.ListBox1.PointToClient(New Point(e.X, e.Y))
'Force the location to be within the horizontal bounds of the ListBox.
If mouseLocation.X < 0 Then
mouseLocation.X = 0
ElseIf mouseLocation.X > Me.ListBox1.Width Then
mouseLocation.X = Me.ListBox1.Width
End If
'Force the location to be within the vertical bounds of the ListBox.
If mouseLocation.Y < 0 Then
mouseLocation.Y = 0
ElseIf mouseLocation.Y > Me.ListBox1.Height Then
mouseLocation.Y = Me.ListBox1.Height
End If
If Me.GetItemIndexAtPoint(mouseLocation) = Me.ListBox1.SelectedIndex Then
'Don't allow the selected item to be dropped on itself.
e.Effect = DragDropEffects.None
Else
'Allow the selected item to be moved.
e.Effect = DragDropEffects.Move
End If
End If
End Sub
Private Sub ListBox1_DragDrop(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles ListBox1.DragDrop
'Test whether the data being dragged is the ListBox itself and the selected item can be moved.
If e.AllowedEffect = DragDropEffects.Move AndAlso _
e.Data.GetDataPresent("System.Windows.Forms.ListBox") AndAlso _
e.Data.GetData("System.Windows.Forms.ListBox") Is Me.ListBox1 Then
Dim selectedIndex As Integer = Me.ListBox1.SelectedIndex
'Get the index of the item being dropped on.
Dim dropIndex As Integer = Me.GetItemIndexAtPoint(Me.ListBox1.PointToClient(New Point(e.X, e.Y)))
'If the item being dropped on is below the selected item, the index of the
'item being dropped on will decrement once the selected item is removed.
If dropIndex > selectedIndex Then
dropIndex -= 1
End If
Dim selectedItem As Object = Me.ListBox1.SelectedItem
Me.ListBox1.Items.Remove(selectedItem)
If dropIndex = -1 Then
'The item was dropped after the last item so add it at the end of the list.
Me.ListBox1.Items.Add(selectedItem)
Else
'Insert the item above the item it was dropped on.
Me.ListBox1.Items.Insert(dropIndex, selectedItem)
End If
Me.ListBox1.SelectedItem = selectedItem
End If
End Sub
Private Function GetItemIndexAtPoint(ByVal location As Point) As Integer
Dim itemIndex As Integer = -1
For index As Integer = 0 To Me.ListBox1.Items.Count - 1
'Test whether the location is within an item.
If Me.ListBox1.GetItemRectangle(index).Contains(location) Then
itemIndex = index
Exit For
End If
Next
Return itemIndex
End Function
4. Run the project and start dragging.
When you drop an item it will be moved to the position above the item you dropped it on. If you drop it after the last item it will be moved to the end of the list.
I request sample drag drop code for a picturebox.
Also how to refuse multiple file drops and limit to single dropped file.
Thanks.
The first thing to note is that the AllowDrop property of the PictureBox class is not designer-visible. I'm not sure why this is because the PictureBox does support drag & drop. As a result you will have to set the property in code.
Now, this first code example will allow you to drop multiple files on the PictureBox but it simply ignores all but the first file:
vb.net Code:
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
'Let the PictureBox accept dropped data.
Me.PictureBox1.AllowDrop = True
End Sub
Private Sub PictureBox1_DragEnter(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles PictureBox1.DragEnter
'Only allow copying and then only if one or more files are being dragged and the first one is an image file.
If (e.AllowedEffect And DragDropEffects.Copy) = DragDropEffects.Copy AndAlso _
e.Data.GetDataPresent("FileDrop", True) AndAlso _
Me.IsImageFile(DirectCast(e.Data.GetData("FileDrop", True), String())(0)) Then
e.Effect = DragDropEffects.Copy
End If
End Sub
Private Sub PictureBox1_DragDrop(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles PictureBox1.DragDrop
''' Determines whether the specified path contains an image file.
''' </summary>
''' <param name="path">
''' The path of the file to test.
''' </param>
''' <returns>
''' <b>True</b> if <i>path</i> contains an image file; otherwise, <b>False</b>.
''' </returns>
Private Function IsImageFile(ByVal path As String) As Boolean
Dim result As Boolean
Try
'Try to create an image from the file.
Using img As Image = Image.FromFile(path)
End Using
'The operation succeeded so the file must contain an image.
result = True
Catch ex As Exception
'The path does not contain a valid image file.
result = False
End Try
Return result
End Function
Analysing this code, in the DragEnter event handler we test whether it is files that are being dragged and that the first one is an image. If that's the case then a copy cursor is displayed. Even if there are other files that are not images they are simply ignored.
In the DragDrop event handler we don't need to test the data again because we know that, if the effect is Copy then the data must have passed the test in the DragEnter event handler. That means we simply get the first file path and load it into the PictureBox.
It should be noted that the IsImageFile method is using a brute force approach to determine whether the file is an image or not. It simply creates an Image object and handles the exception that's thrown if it fails. This is not ideal but there really isn't another way (that I'm aware of) to perform this test.
For clarity, here's the DragEnter event handler rewritten with the code extended out a bit:
vb.net Code:
Private Sub PictureBox1_DragEnter(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles PictureBox1.DragEnter
'Only allow copying and then only if one or more files are being dragged and the first one is an image file.
If (e.AllowedEffect And DragDropEffects.Copy) = DragDropEffects.Copy AndAlso _
e.Data.GetDataPresent("FileDrop", True) Then
Dim data As Object = e.Data.GetData("FileDrop", True)
Dim filePaths As String() = DirectCast(data, String())
Dim firstFilePath As String = filePaths(0)
If Me.IsImageFile(firstFilePath) Then
e.Effect = DragDropEffects.Copy
End If
End If
End Sub
If you want to prevent multiple files being dropped at all then you can do this:
vb.net Code:
Private Sub PictureBox1_DragEnter(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles PictureBox1.DragEnter
'Only allow copying and then only if one file is being dragged and it is an image file.
If (e.AllowedEffect And DragDropEffects.Copy) = DragDropEffects.Copy AndAlso _
e.Data.GetDataPresent("FileDrop", True) Then
Dim data As Object = e.Data.GetData("FileDrop", True)
Dim filePaths As String() = DirectCast(data, String())
If filePaths.Length = 1 Then
Dim firstFilePath As String = filePaths(0)
If Me.IsImageFile(firstFilePath) Then
e.Effect = DragDropEffects.Copy
End If
End If
End If
End Sub
Last edited by jmcilhinney; Dec 10th, 2008 at 09:23 PM.
Also one could use your 'save image in database' code to save the dropped file path to a database.
My last post shows you how to get an Image object from a dropped file and that other thread shows you how to save an Image object to a database. Putting the two together should be a piece of cake and is not something I'll be providing code for explicitly.
Originally Posted by Xancholy
If users can add the image of the file being dropped as custom cursor that would be a complete solution.
I've bookmarked that Code Project article you found and I might look at creating an example that references that C++ code some time in the future.
hey it's me again...great. i didn't see that you had this thread in vb too...
can i ask if it's possible to make the program Reordering Items in a ListBox using a combobox?i can see that GetItemRectangle is not a member of System.Windows.Forms.ComboBox but is it possible to be done or should i stop trying???
thanks for the help...
question please... how do you perform Drag Drop between 2 datagrids BETWEEN 2 different MDI child forms... had a tough time for this one... my apologies... Thanks...
hey it's me again...great. i didn't see that you had this thread in vb too...
can i ask if it's possible to make the program Reordering Items in a ListBox using a combobox?i can see that GetItemRectangle is not a member of System.Windows.Forms.ComboBox but is it possible to be done or should i stop trying???
thanks for the help...
I think you can pretty much forget that one. That would be unintuitive UI design anyway.
question please... how do you perform Drag Drop between 2 datagrids BETWEEN 2 different MDI child forms... had a tough time for this one... my apologies... Thanks...
Do you mean DataGrid or DataGridView. How are the grids populated in the first place?
Is there a way to limit the file type extension? I want to just allow dragging of .pdf files into my listbox.
In the DragEnter event handler you would get the file path and only allow the operation to continue if it had a ".pdf" extension. You'll see in my DragEnter event handlers if have If statements that restrict continuation of the operation to certain conditions. In post #6 that includes getting the file path and passing it to my IsImageFile method. You would get the file path the same way, get its extension using Path.GetExtension and then compare that to ".pdf".
With Me.lvMain.Items.Add(IO.Path.GetFileName(File))
.ImageIndex = ilListView.Images.IndexOfKey(File)
End With
Next
End If
End Sub
Anyway, I always come back to this code because I always forget certain drag & drop things, so thanks for the code!
The first point is quite valid. The second point is also quite valid but, interestingly, I just pasted my code into VS 2008 and there was no warning about ExtractAssociatedIcon being a Shared method, even though Icon was identified as being the Icon property of the form and not the Icon class. I guess that's why I missed it.
With regards to the third point, yes your code is shorter but not necessarily better. If you're going to be adding multiple items to a ListView or other control, or in fact any collection, then the preferred way is to put those items into an array first and then call AddRange rather than calling Add once for each item. This is mainly to avoid lots of events being raised when adding multiple items. It's especially important with controls because each time you add an item the control will be redrawn. If you add 100 items you don't want the control redrawn 100 times, so you call AddRange and it gets redrawn once only.
how do you perform Drag & Drop of a row between 2 datagrids BETWEEN 2 MDI child forms populated either manually or from a recordset initially... i have a common child form with a datagrid which is "like" being duplicated everytime i launch a child form... i progress through programming by referring mostly on examples... but for this issue, i've scoured the net but to no avail.. to date, its been 5 months since my last post and still no luck... hoping for somebody to help me on this topic...
Here's another example using the DataGridView that answers the question of dragging between MDI child forms asked earlier. Sorry to make you wait so long.
Hi jmcilhinney, im having a issue with dragging between 2 listboxes, using your firstcode sample, i have 2 listboxes (listbox 2, and listbox4) and i changed the code to suit the name, but its not working theres no error etc, but the item that i drag from listbox 2 does not spear in listbox 4.
Heres the code i have:
Code:
Private Sub ListBox_MouseDown(ByVal sender As Object, _
ByVal e As MouseEventArgs) Handles ListBox2.MouseDown, _
ListBox4.MouseDown
Dim source As ListBox = DirectCast(sender, ListBox)
For index As Integer = 0 To source.Items.Count - 1
'Test whether the mouse location is within an item
If source.GetItemRectangle(index).Contains(e.Location) Then
'The mouse was depressed on an item so allow a move operation.
source.DoDragDrop(source, DragDropEffects.Move)
Exit For
End If
Next
End Sub
Private Sub ListBox_DragEnter(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles ListBox2.DragEnter, _
ListBox4.DragEnter
Dim source As ListBox = DirectCast(sender, ListBox)
If e.Data.GetDataPresent("System.Windows.Forms.ListBox", False) AndAlso _
e.Data.GetData("System.Windows.Forms.ListBox", False) IsNot source Then
'The data being dragged is a ListBox but not the one that was just entered.
e.Effect = DragDropEffects.Move
End If
End Sub
Private Sub ListBox_DragDrop(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles ListBox2.DragDrop, _
ListBox4.DragDrop
Dim source As ListBox = DirectCast(sender, ListBox)
If e.Data.GetDataPresent("System.Windows.Forms.ListBox", False) Then
'Get the ListBox that the data was dragged from.
Dim data As ListBox = DirectCast(e.Data.GetData("System.Windows.Forms.ListBox", _
False), _
ListBox)
'Make sure we aren't trying to drag from and drop to the same control.
If data IsNot source Then
'Get the item that was dragged.
Dim item As Object = data.SelectedItem
'Remove the item from its original location.
data.Items.Remove(item)
'Get the current mouse location relative to the control being dropped on.
Dim location As Point = source.PointToClient(New Point(e.X, e.Y))
Dim dropIndex As Integer = -1
'Find the item over which the mouse was released.
For index As Integer = 0 To source.Items.Count - 1
If source.GetItemRectangle(index).Contains(location) Then
dropIndex = index
Exit For
End If
Next
If dropIndex = -1 Then
'The mouse was not released over an item so add the new item to the end.
source.Items.Add(item)
Else
'Insert the new item above the item it was dropped on.
source.Items.Insert(dropIndex, item)
End If
End If
End If
End Sub
There's nothing at all wrong with that code. It works perfectly, exactly as it should. What's different about your code compared to mine? You don't have my Load event handler. Is there anything in my Load event handler that might be important? Also, in my first post I provided two links to information that you should read if you're interested in drag & drop. The second of those two links covers why you're having an issue. You presumably didn't read that information. If you simply copy and paste code then you are quite likely to not understand it properly, which is why I provided those links.
The allow drop code i have, but the above code is just to populate the lists, since my lists are already populated it is not needed. I have the links bookmarked to read today since i was just on my way to bed after posting last night, so ill read those now.
I copied and pasted your code into a new project and it worked perfectly. The only thing extra that I had to do was set the AllowDrop properties of the two ListBoxes to True. If that code is not working for you then the only reason I can see would be that you haven't done that.
Strange, because besides having the allow drop set via the load event i also tried setting it int he listbox properties to see if that made any difference but it never.
When i click/drag from listbox2 the symbol to show that im dragging appears, but when dropped on listbox 4 it doesn't show up, would how the list box is populated matter? Because mine is populated from a dirInfoArray.
As long as the items are added directly to the ListBox and not bound then there's no reason it shouldn't work. If the data is bound then you would have to work with the items in the data source(s) and not in the control(s), which is always the case with bound data.
I saved a link to this because I thought I would use it some day, and now I was able to do so. Actually, that's probably not the case, since I've done lots of drag and drop, it's just that JMC wrote one specific example that I had never done myself, but which I was doing for this project.
My one question, in case this thread is still occasionally observed, is why there is the GetItemIndexAtPoint method when there is the IndexFromPoint method for the listbox already. I don't see any advantage to the custom method over the built-in method.
My one question, in case this thread is still occasionally observed, is why there is the GetItemIndexAtPoint method when there is the IndexFromPoint method for the listbox already. I don't see any advantage to the custom method over the built-in method.
I can only assume that I didn't notice that existing method at the time.
I saw this Topic from outside, and I had to login just to Thanks @jmcilhinney for the Hardwork and amazing Job. This topic has now become my favorit Topic on vBForums. I did not expect finding such a usefull topic when I first saw the Title.
Thanks jmcilhinney, Your hard work has definitely paid off brother!
+Rep
A huge thanks to all the Great Developers and Helpers on vBForums for helping me and many others! Special thanks to Dunfiddlin, Paul, TechnoGome, , JayInThe813, ident for helping me with my projects througout the years. Incl. those i forgot to mention!
I have been playing around with the amended example, which does indeed drag and drop multiple items. One thing that is a little confusing is that it works in a different way to windows normally.
If in windows explorer, you select multiple items,by clicking the first one, then pressing shift clicking (and releasing) on the last item, the selection is complete. If you then click & Hold on any of the items selected, you can then drag all the selected items.
If however you repeat the process with the example code, when you click and hold any of the previously selected items, they are all de selected apart from the one you have clicked on.
is it possible to make it work the same as in Windows Explorer ?
I have stepped thro the different sections of the code and from what I can see the selection & highlighting of the individual selected items are part of the core windows code and not part of the code that I can amend. It is only the actual drag and drop that is coded. There of course be some control that I am not aware of.