首页 > 解决方案 > 执行拖放操作,如 Windows 资源管理器

问题描述

我有一个可以拖放 SVG 文件的应用程序。这是适用于 Adob​​e XD(支持 SVG 文件)等应用程序的工具。执行基本的拖放操作非常简单。

Dim dataObj As New DataObject(DataFormats.FileDrop, New String() {_svgPath})
PictureBox.DoDragDrop(dataObj, DragDropEffects.Copy)

它有效!如果我想将文件拖放到资源管理器中,那么一切正常。.png此外,如果我将要绘制的文件或字符串拖放到编辑器:它可以工作。

现在的问题是:当涉及到其他第三方应用程序时,它会变得有点混乱。您想将 SVG 文件从您的应用程序拖放到 Adob​​e XD?不,这行不通!要将 SVG 文件从文件夹拖放到 Adob​​e XD?这将毫无问题地工作。

这种令人困惑的情况不仅出现在 Adob​​e XD 中。它们是大量其他程序,在使用资源管理器时可以使用拖放操作,但您的“自己创建的”拖放操作失败了。

我已经尝试了很多。用不同的数据格式、不同的 DragDropEffects 对其进行了测试……没有任何效果。就像我错过了什么。我已经在 GitHub 上搜索了不同的DoDragDrop()功能,在 .NET Docs 中搜索只是为了看看是否缺少某些东西。

我在有关该DoDragDrop()功能的 System.Windows.Forms.Control 的参考源中找到了这一点:

开始拖动操作。allowedEffects 确定可以发生哪些拖动操作。如果拖动操作需要与另一个进程中的应用程序互操作,则数据应该是基本托管类(字符串、位图或元文件)或实现 System.Runtime.Serialization.ISerializable 的某个对象。data 也可以是任何实现 System.Windows.Forms.IDataObject 的对象。

但是这个信息也不是很有帮助。

Windows 资源管理器如何创建它的 DragDrop 操作以及如何在 .Net 中进行这样的 DragDrop 操作(如果它在 vb.net 或 c# 中无关)?我需要对 DataObject 做更多的事情吗?改造它?更改?

标签: .netvb.netwinformsdrag-and-drop

解决方案


这些是Drag&Drop涉及DataFormats.FileDrop数据类型的操作的基本要求。
如果源文件类型受 Windows GDI 相关方法(BitBlt大多数情况下)支持,则包括源文件的缩略图图像。

Drag&Drop操作开始时 - 将鼠标拖到 a 上PictureBox- 原始.svg文件路径被添加到专门的StringCollection类中。
然后,该StringCollection路径包含在使用DataObject.SetFileDropList()方法传递给DoDragDrop方法的DataObject集合中,以及DragDropEffects的扩展选择(根据需要设置)。

这里使用的SVGImagePath字段是指原始.svg文件路径。

Jpeg使用 PhotoShop、FireFox、Windows Paint、Visual Studio Image Editor 测试的Win GDI Image source ( )。
.svg使用 FireFox 和 Edge 测试的图像。

.Net Version: 4.7.1
Visual Studio version: 15.7.5

Imports System.Collections.Specialized

Private SVGImagePath As String = "[Source SVG File]"

Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
    If sender IsNot Nothing AndAlso (e.Button = MouseButtons.Left) Then

        Dim dataObject As New DataObject()
        Dim FilePathsItems As New StringCollection()
        FilePathsItems.Add(SVGImagePath)

        Dim thumbCallback As Image.GetThumbnailImageAbort =
            Function()
                Return False
            End Function
        dataObject.SetImage(New Bitmap(PictureBox1.Image.GetThumbnailImage(64, 64, thumbCallback, IntPtr.Zero)))
        dataObject.SetFileDropList(FilePathsItems)
        PictureBox1.DoDragDrop(dataObject, (DragDropEffects.Copy Or DragDropEffects.Link))
    End If
End Sub

C#原始代码:

using System.Collections.Specialized;

private string SVGImagePath = string.Empty;

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        //Image.GetThumbnailImageAbort thumbCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback);
        //FilePathsItems.Add(((FileInfo)listBox1.SelectedItem).FullName);
        DataObject dataObject = new DataObject();
        StringCollection FilePathsItems = new StringCollection();
        FilePathsItems.Add(SVGImagePath);

        Image.GetThumbnailImageAbort thumbCallback = ()=> { return false; };
        dataObject.SetImage(new Bitmap(pictureBox1.Image.GetThumbnailImage(64, 64, thumbCallback, IntPtr.Zero)));
        dataObject.SetFileDropList(FilePathsItems);
        pictureBox1.DoDragDrop(dataObject, (DragDropEffects.Copy | DragDropEffects.Link));
    }
}

推荐阅读