Ich möchte eine Anwendung schreiben, die Zip-Dateien durch direktes Ziehen und Ablegen von Dateien aus Visual Studio Solution Explorer in meine App erstellt.
Ich habe das folgende Codefragment verwendet, um das eingehende DataObject abzufangen:
private void lblIncludedFiles_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.Copy;
}
}
Ich habe jeden möglichen Wert von ausprobiert DataFormats
, alle geben false zurück.
Da diese Aufgabe möglicherweise etwas weniger einfach ist als auf dem Papier, finden Sie hier ein Beispielverfahren, mit dem Sie eine Liste der Dateien abrufen können, die aus dem Visual Studio Solution Explorer-Bedienfeld gezogen wurden.
Die von DataFormats
Visual Studio generierten Dateien sind teilweise üblich ( UnicodeText
und Text
), aber die eigentliche Dateiliste wird in einem (klassischen) MemoryStream-Objekt weitergegeben, das kein Befehl ist DataFormat
: CF_VSSTGPROJECTITEMS
.
Der MemoryStream enthält Unicode-Text - die tatsächliche Liste der Projekt + Dateinamen-Tupel, die gelöscht werden - getrennt durch ein Pipe ( |
) -Symbol - und einige andere Binärabschnitte, die ich hier nicht für nützlich halte.
Das andere nicht gebräuchliche / vordefinierte Format VX Clipboard Descriptor Format
ist ebenfalls ein MemoryStream-Objekt, aber es ist nur eine Unicode-Zeichenfolge, die den Projektnamen enthält.
In diesem Beispiel werden die kombinierten Elemente, die Teil des Abwurfs sind, mithilfe eines benutzerdefinierten Klassenobjekts organisiert, das Informationen zu folgenden Themen enthält:
.[xxx]prj
),.cs
, .vb
, .h
, .png
etc.)Wählen Sie ein Steuerelement aus, das den Drop erhält, und fügen Sie die Handler hinzu:
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)
{
var vsObject = new VisualStudioDataObject(e.Data);
}
Das Klassenobjekt VisualStudioDataObject
enthält die Methoden, die zum Extrahieren der Informationen aus dem DataObject
vom DragDrop
Ereignis referenzierten Objekt erforderlich sind DragEventArgs
:
(Getestet mit Visual Studio 2017)
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(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(format, 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");
}
}
}
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen