visual soltar formulario eventos arrastrar c# winforms drag-and-drop

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"