formulario - C#WinForms: identifica el tipo de evento de acción de arrastrar y soltar
arrastrar y soltar en c# (1)
Aquí tengo el código fuente de solución que permite soltar solo elementos de outlook. aquí están los manejadores de eventos:
private void Form1_DragEnter(object sender, DragEventArgs e)
{
//display formats available
this.label1.Text = "Formats:/n";
foreach (string format in e.Data.GetFormats())
{
this.label1.Text += " " + format + "/n";
}
//ensure FileGroupDescriptor is present before allowing drop
if (e.Data.GetDataPresent("FileGroupDescriptor"))
{
e.Effect = DragDropEffects.All;
}
}
private void Form1_DragDrop(object sender, DragEventArgs e)
{
//wrap standard IDataObject in OutlookDataObject
OutlookDataObject dataObject = new OutlookDataObject(e.Data);
//get the names and data streams of the files dropped
string[] filenames = (string[])dataObject.GetData("FileGroupDescriptorW");
MemoryStream[] filestreams = (MemoryStream[])dataObject.GetData("FileContents");
this.label1.Text += "Files:/n";
for (int fileIndex = 0; fileIndex < filenames.Length; fileIndex++)
{
//use the fileindex to get the name and data stream
string filename = filenames[fileIndex];
MemoryStream filestream = filestreams[fileIndex];
this.label1.Text += " " + filename + "/n";
//save the file stream using its name to the application path
FileStream outputStream = File.Create(filename);
filestream.WriteTo(outputStream);
outputStream.Close();
}
}
El caso de uso: los usuarios necesitan la capacidad de arrastrar y soltar elementos de correo electrónico desde Outlook a un formulario en mi aplicación WinForms (.Net 4). La aplicación guarda estos elementos en formato .msg y los almacena en una ubicación predeterminada.
El problema: mi código no es robusto contra arrastrar y soltar desde otras fuentes (por ejemplo, arrastrar un jpeg desde IE al formulario desencadena el mismo evento). Esto se debe a que no puedo determinar si el elemento arrastrado es un objeto de Outlook o de qué origen provienen los elementos arrastrados.
¿Hay alguna solución para que solo pueda aceptar artículos de arrastrar y soltar de un tipo en particular? Aquí está mi código en el controlador de eventos DragDrop:
Outlook.Application outlook = new Outlook.Application();
Outlook.Selection sel = outlook.ActiveExplorer().Selection;
try
{
foreach (object item in sel)
{
if (item is Outlook.MailItem)
{
var mail = item as Outlook.MailItem;
CopyMailItemToLocalTempDir(mail);
txtComment.Text = "Email from " + mail.SenderName + " Regarding " + mail.Subject;
}
}
}
finally
{
// This is hokey but it prevents Outlook from remembering previously selected items
// - refer http://stackoverflow.com/questions/14090420/interop-outlook-doesnt-clear-selected-mails-at-drag-and-drop
var folder = outlook.ActiveExplorer().CurrentFolder;
outlook.ActiveExplorer().CurrentFolder = outlook.GetNamespace("MAPI").GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
Thread.Sleep(50);
outlook.ActiveExplorer().CurrentFolder = folder;
Marshal.ReleaseComObject(sel);
Marshal.ReleaseComObject(outlook);
sel = null;
outlook = null;
}
Algunos detalles sobre el objeto DragEventArgs (e) al arrastrar desde Outlook:
e.Data.GetFormats() returns:
{string[15]}
[0]: "RenPrivateSourceFolder"
[1]: "RenPrivateLatestMessages"
[2]: "RenPrivateMessages"
[3]: "RenPrivateItem"
[4]: "FileGroupDescriptor"
[5]: "FileGroupDescriptorW"
[6]: "FileDrop"
[7]: "FileNameW"
[8]: "FileName"
[9]: "FileContents"
[10]: "Object Descriptor"
[11]: "System.String"
[12]: "UnicodeText"
[13]: "Text"
[14]: "CSV"
e.Data.GetData("Text") returns:
"From/tSubject/tReceived/tSize/tCategories/t/r/nJoe Sender/tThis is the email subject/t10:51 AM/t3 KB/t/t"