views:

172

answers:

2

I'm trying to drag files into my application from a program called Locate32 (which is great by the way). Here is what happens:

e.Data.GetFormats()
{string[7]}
    [0]: "FileDrop"
    [1]: "FileNameW"
    [2]: "FileName"
    [3]: "FileNameMap"
    [4]: "FileNameMapW"
    [5]: "Shell IDList Array"
    [6]: "Shell Object Offsets"
DataFormats.FileDrop
"FileDrop"
e.Data.GetDataPresent(DataFormats.FileDrop)
false

Why does e.Data.GetDataPresent(DataFormats.FileDrop) return false even though FileDrop is clearly one of the formats listed as "available"?

If I do e.Data.GetData(DataFormats.FileDrop) I get a list of a bunch of filenames, as I should. Also, drag and drop works fine from Windows Explorer.

Here's the code for my DragEnter handler:

private void MyForm_DragEnter(object sender, DragEventArgs e) {
    if(e.Data.GetDataPresent(DataFormats.FileDrop)) {
        e.Effect = DragDropEffects.Copy;
    } else {
        e.Effect = DragDropEffects.None;
    }
}
A: 

You should take a look into e.AllowedEffect if DragDropEffects.Copy is within the list.

Update

Some time ago i also had some problems with getting the right format out of the GetDataPresent(). Due to this fact, i just looked directly into the list provided by GetFormats() and did it on myself. The code was something like that:

private void OnItemDragEnter(object sender, DragEventArgs e)
{
    //Get the first format out of the list and try to cast it into the
    //desired type.
    var list = e.Data.GetData(e.Data.GetFormats()[0]) as IEnumerable<ListViewItem>;
    if (list != null)
    {
        e.Effect = DragDropEffects.Copy;
    }
    else
    {
        e.Effect = DragDropEffects.None;
    }
}

This simple solution works for me, but you could also walk all over the GetFormats() array with linq and try to find your desired type by IEnumerable<T>.OfType<MyType>() or something similar.

Oliver
Yes, `e.AllowedEffect` "contains" `DragDropEffects.Copy` for both Locate32 and Windows Explorer. The issue is an apparent mismatch between `e.Data.GetDataPresent()` and `e.Data.GetFormats()`. I tried looking in Reflector but I really don't understand what's going on in there.
jnylen
Since your update is close to what I'm doing now, I'll accept your solution. However, I don't see any need to try and grab all the data until it's actually needed (i.e. in the DragDrop event handler).
jnylen
A: 

Unless someone can tell me why this is a bad idea, here's what I'm going to go with:

private void MyForm_DragEnter(object sender, DragEventArgs e) {
    e.Effect = (e.Data.GetFormats().Any(f => f == DataFormats.FileDrop)
        ? DragDropEffects.Copy
        : DragDropEffects.None);
}

Works from both Windows Explorer and Locate32.

jnylen