我有一个可以拖放n SVG文件的应用程序。这是用于Adobe XD之类的应用程序的工具(支持SVG文件)。执行基本的拖放操作非常简单。
Dim dataObj As New DataObject(DataFormats.FileDrop, New String() {_svgPath})
PictureBox.DoDragDrop(dataObj, DragDropEffects.Copy)
它有效!如果我想将文件拖放到资源管理器中,则一切正常。另外,如果我拖动n拖放一个“ .png”文件以绘画或一个字符串到编辑器:它也可以。
现在的问题是:当涉及其他第三方应用程序时,它将变得有些混乱。您想将SVG文件从应用程序拖放到Adobe XD吗?不,这行不通!您想将SVG文件从文件夹拖放到Adobe XD吗?这将正常工作。
这种混乱的情况不仅出现在Adobe XD中。它们有大量其他程序,使用资源管理器时可以进行“拖放”操作,但是“自己创建的”拖放操作失败。
我已经尝试了很多。使用不同的DataFormats,不同的DragDropEffects测试了它……没有任何效果。就像我错过了什么。我已经在GitHub上搜索了不同的DoDragDrop()
函数,并在.NET Docs中进行了搜索,以查看是否缺少某些内容。
我在有关DoDragDrop()
函数的System.Windows.Forms.Control的参考源中找到了这一点:
开始拖动操作。 allowedEffects确定可以进行哪些拖动操作。如果拖动操作需要与另一个进程中的应用程序互操作,则数据应该是基本托管类(字符串,位图或图元文件),或者是某些实现System.Runtime.Serialization.ISerializable的对象。数据也可以是实现System.Windows.Forms.IDataObject的任何对象。
但是此信息也没有真正帮助。
Windows资源管理器如何创建其DragDrop操作,如何在.Net中进行这样的DragDrop操作(如果在vb.net或c#中无关)?我需要对DataObject做更多的事情吗?改造吗?改变吗?
答案 0 :(得分:1)
这些是涉及DataFormats.FileDrop数据类型的Drag&Drop
操作的基本要求。
如果Windows GDI相关方法(主要是BitBlt
)支持源文件类型,则包括源文件的缩略图图像。
开始Drag&Drop
操作时-将鼠标拖动到PictureBox
上-原始.svg
文件路径被添加到专门的StringCollection类中。
然后,将StringCollection
路径包括在使用DataObject方法传递到DoDragDrop方法的DataObject.SetFileDropList()集合中,并包含DragDropEffects的扩展选择。 />
此处使用的SVGImagePath
字段是指原始.svg
文件路径。
Win GDI图像源(
Jpeg
)已通过PhotoShop,FireFox,Windows Paint,Visual Studio图像编辑器进行了测试。
.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)
ListBox1.DoDragDrop(dataObject, (DragDropEffects.All Or DragDropEffects.Link))
End If
End Sub
C#
原始代码:
using System.Collections.Specialized;
private string SVGImagePath = string.Empty;
private void pictureBox2_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(pictureBox2.Image.GetThumbnailImage(64, 64, thumbCallback, IntPtr.Zero)));
dataObject.SetFileDropList(FilePathsItems);
listBox1.DoDragDrop(dataObject, (DragDropEffects.All | DragDropEffects.Link));
}
}
答案 1 :(得分:0)
吉米的答案是正确的。我在Jimi代码中的问题是缩略图图像的生成。您的目标应用程序可能会因此而阻止D&D操作。如果您等待几秒钟(也许是GetThumbnailImage
花费时间),那么目标应用程序将允许该文件。我将个人密码留作答案。
Dim dataObj As New DataObject
Dim filePaths = New List(Of String) From {New System.IO.FileInfo(_svgPath).FullName}
Dim sc = New System.Collections.Specialized.StringCollection()
sc.AddRange(filePaths.ToArray())
dataObj.SetFileDropList(sc)
PictureBox.DoDragDrop(dataObj, DragDropEffects.Copy)
再次:特别感谢@Jimi的努力<3