我想编写一个生成zip文件的应用程序,直接将文件从Visual Studio Solution Explorer拖放到我的应用程序中。
我使用以下代码片段来捕获传入的DataObject:
private void lblIncludedFiles_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.Copy;
}
}
我已经尝试了DataFormats
的所有可能值,所有这些都返回false。
由于此任务可能不像在纸上看起来那么简单,因此这里有一个示例过程,应该允许从Visual Studio Solution Explorer面板中获取拖动的文件列表。
Visual Studio生成的DataFormats
部分常见(UnicodeText
和Text
),但实际的文件列表是在(经典)MemoryStream对象中传递的,该对象不是commons DataFormat
:CF_VSSTGPROJECTITEMS
。
MemoryStream包含Unicode文本 - 正在删除的Project + File Name元组的实际列表 - 由管道(|
)符号分隔 - 以及其他一些我认为在这里无法描述的二进制部分。
另一种非常见/预定义格式VX Clipboard Descriptor Format
也是一个MemoryStream对象,但它只是一个包含Project名称的Unicode字符串。
在此示例中,作为Drop的一部分的组合元素使用包含以下信息的自定义类对象进行组织:
.[xxx]prj
),.cs
,.vb
,.h
,.png
等)选择一个将接收Drop的控件并添加处理程序:
private void ctlVSDrop_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetFormats().Contains("CF_VSSTGPROJECTITEMS"))
{
e.Effect = DragDropEffects.Copy;
}
}
private void ctlVSDrop_DragDrop(object sender, DragEventArgs e)
{
VisualStudioDataObject vsObject = new VisualStudioDataObject(e.Data);
}
一个类对象VisualStudioDataObject
包含从DataObject
事件DragDrop
引用的DragEventArgs
中提取信息所需的方法:
(使用Visual Studio 2017测试)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
class VisualStudioDataObject
{
public VisualStudioDataObject(IDataObject data)
{
if (data is null) {
throw new ArgumentNullException("IDataObject data", "Invalid DataObject");
}
this.FileList = new List<FileObject>();
GetData(data);
}
public List<FileObject> FileList { get; private set; }
public string ProjectUUID { get; private set; }
public string ProjectPath { get; private set; }
public string ProjectFilePath { get; private set; }
public string StartingObject { get; private set; }
public class FileObject
{
public FileObject(string project, string path, string type) {
this.SourceProject = project;
this.FilePath = path;
this.FileType = type;
}
public string SourceProject { get; }
public string FilePath { get; }
public string FileType { get; }
}
private void GetData(IDataObject data)
{
List<string> formats = data.GetFormats(false).ToList();
if (formats.Count == 0) return;
foreach (string format in formats)
{
switch (format)
{
case "UnicodeText":
this.StartingObject = data.GetData(DataFormats.UnicodeText, true).ToString();
break;
case "VX Clipboard Descriptor Format":
var projectMS = (MemoryStream)data.GetData("VX Clipboard Descriptor Format", false);
projectMS.Position = 0;
string prjFile = Encoding.Unicode.GetString(projectMS.ToArray()).TrimEnd("\0".ToCharArray());
this.ProjectFilePath = prjFile;
this.ProjectPath = Path.GetDirectoryName(prjFile);
break;
case "CF_VSSTGPROJECTITEMS":
GetFileData((MemoryStream)data.GetData("CF_VSSTGPROJECTITEMS", false));
break;
}
}
}
private void GetFileData(MemoryStream ms)
{
string uuidPattern = @"\{(.*?)\}";
string content = Encoding.Unicode.GetString(ms.ToArray());
//Get the Project UUID and remove it from the data object
var match = Regex.Match(content, uuidPattern, RegexOptions.Singleline);
if (match.Success) {
this.ProjectUUID = match.Value;
content = content.Replace(this.ProjectUUID, "").Substring(match.Index);
//Split the file list: Part1 => Project Name, Part2 => File name
string[] projectFiles = content.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < projectFiles.Length; i += 2)
{
string sourceFile = projectFiles[i + 1].Substring(0, projectFiles[i + 1].IndexOf("\0"));
this.FileList.Add(new FileObject(projectFiles[i], sourceFile, Path.GetExtension(sourceFile)));
}
}
else
{
this.FileList = null;
throw new InvalidDataException("Invalid Data content");
}
}
}
我尝试使用TreeView控件解决问题:
Tree.AllowDrop = true;
Tree.DragEnter += (s, e) =>
{
e.Effect = DragDropEffects.Move;
};
Tree.DragDrop += (s, e) =>
{
var data = e.Data;
var value = data.GetData(typeof(string));
};
从树中的解决方案资源管理器中删除cs-File后,您可以读出cs-File的路径。可用于将文件转换为zip的路径。
>>> value = "C:\\Users\\Name\\Desktop\\Projekte\\Projekte-Visual Studio\\Project\\Project\\Classes\\Method.cs"
希望能帮助到你。