There's a really good example from someone who's done this.. The main problem with your code is that you need to set e.Effect
or the DragDrop method isn't fired:
void listBoxLayers_DragEnter(object sender, DragEventArgs e)
{
DataFormats.Format esriLayerFormat = DataFormats.GetFormat("ESRI Layers");
if (e.Data.GetDataPresent(esriLayerFormat.Name))
{
e.Effect = DragDropEffects.Copy;
}
}
The next big step is to get the layers... because DragDrop is a Microsoft Windows event it needs to follow the Microsoft Windows rules which will copy the objects outside of the STA thread as a binary object that needs to be converted (deserialized) back into an Esri object on the tread to be useful in this context:
void listBoxLayers_DragDrop(object sender, DragEventArgs e)
{
DataFormats.Format esriLayerFormat = DataFormats.GetFormat("ESRI Layers");
Guid pUID = new Guid("{34C20002-4D3C-11D0-92D8-00805F7C28B0}"); // Esri Layer GUID
if (e.Data.GetDataPresent(esriLayerFormat.Name))
{
System.IO.MemoryStream pDataStream = (System.IO.MemoryStream)e.Data.GetData(esriLayerFormat.Name, true);
IMemoryBlobStreamVariant pMemBlobVar = new MemoryBlobStreamClass();
pMemBlobVar.ImportFromVariant(pDataStream.ToArray());
IStream pStream = (IStream)pMemBlobVar;
IObjectStream pObjStream = new ObjectStreamClass();
pObjStream.Stream = pStream;
byte pv; // variables for the Microsoft method of the object stream
uint cb = sizeof(int);
uint pcbRead;
pObjStream.RemoteRead(out pv, cb, out pcbRead); // https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.dts.runtime.wrapper.istream.remoteread.aspx
List<ILayer> pLayerList = new List<ILayer>();
for (byte Cnt = 0; Cnt < pv; Cnt++)
{
// you could probably go straight to adding the converted object
// like pLayerList.Add((ILayer)pObjStream.LoadObject(pUID, null));
// to the list but showing it in 3 lines makes the process clearer I think
object o = pObjStream.LoadObject(pUID, null);
ILayer pThisLayer = (ILayer)o;
pLayerList.Add(pThisLayer); // Add to the list of layers dropped
}
}
}
I have condensed the objects in the provided example to specifically ILayer objects. The DragDrop method will have a List object containing all the ILayer objects dropped onto the control, how you use this is up to you and the requirements of the rest of your program.. it might be safe to make the list global and reset/append by dragdrop then the data dropped will be available to other form events (like button click).