【问题标题】:e.Data.GetDataPresent not working in WinForms drag-and-drop handler?e.Data.GetDataPresent 在 WinForms 拖放处理程序中不起作用?
【发布时间】:2010-05-17 16:31:29
【问题描述】:

我正在尝试将文件从名为 Locate32 的程序拖到我的应用程序中(顺便说一句,这很棒)。这是发生了什么:

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

为什么 e.Data.GetDataPresent(DataFormats.FileDrop) 会返回 false,尽管 FileDrop 显然是列为“可用”的格式之一?

如果我这样做e.Data.GetData(DataFormats.FileDrop),我应该得到一堆文件名的列表。此外,从 Windows 资源管理器中拖放也可以正常工作。

这是我的 DragEnter 处理程序的代码:

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

【问题讨论】:

  • 您的操作系统版本是多少?您是否使用调试器逐步完成此操作以查看您的 DragEnter 事件是否正在引发?
  • 这发生在 XP 和 Win7 中。是的,它正在被提出——我发布的第一个块是我在MyForm_DragEnter 的第一行打破并在即时窗口中做一些事情。

标签: c# winforms drag-and-drop


【解决方案1】:

如果DragDropEffects.Copy 在列表中,您应该查看e.AllowedEffect

更新

前段时间,我在从GetDataPresent() 中获取正确格式时也遇到了一些问题。由于这个事实,我只是直接查看了GetFormats() 提供的列表并在自己身上做了。代码是这样的:

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;
    }
}

这个简单的解决方案对我有用,但您也可以使用 linq 遍历 GetFormats() 数组,并尝试通过 IEnumerable&lt;T&gt;.OfType&lt;MyType&gt;() 或类似的东西找到您想要的类型。

【讨论】:

  • 是的,e.AllowedEffect“包含”DragDropEffects.Copy 用于 Locate32 和 Windows 资源管理器。问题是e.Data.GetDataPresent()e.Data.GetFormats() 之间明显不匹配。我尝试查看 Reflector,但我真的不明白那里发生了什么。
  • 由于您的更新与我现在所做的接近,我会接受您的解决方案。但是,在实际需要之前(即在 DragDrop 事件处理程序中),我认为没有必要尝试获取所有数据。
  • 我完全被 GetDataPresent 弄糊涂了,并确信它的工作方式与 IsAssignableFrom.... 所以,如果你有一个由同一层次结构中的项目组成的控件,你会据我所知,需要对每种类型进行检查......这里没有多态......
【解决方案2】:

除非有人能告诉我为什么这是一个坏主意,否则我将采用以下方法:

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

适用于 Windows Explorer 和 Locate32。

【讨论】:

    猜你喜欢
    • 2014-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多