![]() |
Drag and Drop |
|
| Home « Computers « DevBlog | ||
Back to: Development Blog Contents
How to drag and drop from Windows Explorer into a .NET Forms application
Implementing drag and drop in the C++/MFC days created a fragile nightmare of complex code, but I'd noticed that .NET had introduced apparently simple classes and events to wrap all the complexity. In May 2004 I finally got the change to try out drag and drop in the Framework as I needed to drop folders from Windows Explorer into my app.
Most of my app was filled with a C1TrueDBGrid, so I set it's AllowDrop property to true and added handlers for the DragEnter and DragDrop handlers. When the dragging cursor went over my control I at first got the "forbidden drop" icon and no DragDrop event triggered. My code looked correct, so I asked in the Stanski mailing list about this. Thanks to Greg S who pointed out that I had forgotten to set the DragDropEffects property in the DragEnter event, which is how you tell the shell that a drop is allowed. D'oh! Once you've set event argument e.Effect = DragDropEffects.Copy you'll receive DragDrop events.
The event code was trivial, but I found I had to carefully inspect the contents of the e.Data object inside DragEnter to find out what was being dropped from Windows Explorer and either accept or reject the drop accordingly. The e.Data object implements the rather vague IDataObject interface.
I wrote some code to dump the contents of the e.Data object. Use e.Data.GetFormats() to set a string array of format types, then call e.Data.GetData(formatType,false) to get an object for each format. Here's a sample of what I found:
0 Shell IDList Array - MemoryStream [Len=463] 0x010000000c000000910100001... 1 Shell Object Offsets - MemoryStream [Len=16] 0x110000001a000000f6ffffffd8fff... 2 DragImageBits - MemoryStream [Len=4344] 0x3c000000120000000d000000090... 3 DragContext - MemoryStream [Len=16] 0x00000000010000000000000000000000 4 InShellDragLoop - MemoryStream [Len=4] 0x00000000 5 FileDrop - String[] D:\temp\reports,D:\temp\junk 6 FileNameW - String[] D:\temp\reports 7 FileName - String[] D:\temp\reports
You can see some MemoryStream objects which seem to contain shell and PIDL information, which I thankfully no longer need to worry about. The only format that seems to matter is FileDrop. I found that if I dropped multiple selected files or folders into my control I would get all of the names in the FileDrop string array (see two names in my dump).
So basically, you need to code this to get the file(s) or folder(s) dropped into your control:
string[] names = (string[])e.Data.GetData("FileDrop",false);
You will probably want to add some defensive code around this single line to make sure you don't run into an Exception. Get the names, then validate them in the DragEnter event and process them in the DragDrop event.
Here is the code I wrote to dump an object that implements the IDataObject interface:
public static string DumpDataObject(IDataObject ido) |
Back to: Development Blog Contents