【问题标题】:Drag & Drop for SpecialFolders特殊文件夹的拖放
【发布时间】:2011-11-14 17:21:08
【问题描述】:

我有一个应用程序,它允许用户将文件或整个文件夹拖放到一个特殊的“放置区域”中,此时所有文件都会被处理。该应用程序正在使用 WPF 开发,并且此特定 XAML 视图将“AllowDrop”设置为 true,并在代码隐藏中处理 Drop 事件。

一切都适用于普通文件和标准 Windows 文件夹。但是,如果用户删除了一个特殊的 Windows 文件夹(例如,图片、视频),则该功能将不起作用。看起来这是因为 DragEventArgs.Data 的内容不是 DataFormats.FileDrop 枚举。其他文件夹或文件则不然。

我处理掉落的部分代码是:

private void OnDrop(object Sender, DragEventArgs E)
{
    if (E.Data.GetDataPresent(DataFormats.FileDrop))
    {
        var _droppedFilePaths = E.Data.GetData(DataFormats.FileDrop, true) as string[];

        // Process the files....
    }
}

有什么方法可以识别drop数据包含Windows 7图片库并映射回其实际路径?

【问题讨论】:

  • This page 似乎有 Jim Barry 的答案。看起来不好玩。

标签: wpf drag-and-drop special-folders


【解决方案1】:

使用here描述的解决方案,我写了如下方法:

const string ShellIdListArrayName = "Shell IDList Array";

static IEnumerable<string> GetPathsFromShellIDListArray(IDataObject data)
{
    if (data.GetDataPresent(ShellIdListArrayName))
    {
        var ms = (MemoryStream)data.GetData(ShellIdListArrayName);
        byte[] bytes = ms.ToArray();

        IntPtr p = Marshal.AllocHGlobal(bytes.Length);
        Marshal.Copy(bytes, 0, p, bytes.Length);
        uint cidl = (uint)Marshal.ReadInt32(p, 0);

        int offset = sizeof(uint);
        IntPtr parentpidl = (IntPtr)((int)p + (uint)Marshal.ReadInt32(p, offset));
        StringBuilder path = new StringBuilder(256);
        SHGetPathFromIDList(parentpidl, path);

        for (int i = 1; i <= cidl; ++i)
        {
            offset += sizeof(uint);
            IntPtr relpidl = (IntPtr)((int)p + (uint)Marshal.ReadInt32(p, offset));
            IntPtr abspidl = ILCombine(parentpidl, relpidl);
            if (SHGetPathFromIDList(abspidl, path) != 0)
            {
                yield return path.ToString();
            }
            ILFree(abspidl);
        }
    }
}

[DllImport("shell32.dll")]
public static extern int SHGetPathFromIDList(IntPtr pidl, StringBuilder pszPath); 

[DllImport("shell32.dll")]
public static extern IntPtr ILCombine(IntPtr pidl1, IntPtr pidl2);

[DllImport("shell32.dll")]
public static extern void ILFree(IntPtr pidl);

您可以将 e.Data 从您的事件处理程序传递给此方法,您将获得一系列路径(假设这些项目当然有路径......例如,“我的电脑”没有一条路径)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-10
    相关资源
    最近更新 更多