2013-07-03 14 views
9

Il caso d'uso delle attività: In gli utenti hanno bisogno la possibilità di trascinare gli elementi & goccia di posta elettronica da Outlook in un form nel mio WinForms (.Net 4) applicazione. L'applicazione salva questi elementi nel formato .msg e li memorizza in una posizione predeterminata.C# WinForms: tipo di trascinamento evento azione

Il problema: il mio codice non è robusto contro il trascinamento da altre fonti (ad esempio il trascinamento di un JPEG da IE sul modulo attiva lo stesso evento). Ciò è dovuto al fatto che non è possibile determinare se l'elemento trascinato è un oggetto di Outlook o da quale origine provengono gli oggetti trascinati.

Esiste una soluzione alternativa che consente di accettare solo voci di trascinamento di un tipo particolare? Ecco il mio codice nel gestore di eventi 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; 
} 

Alcuni dettagli sull'oggetto DragEventArgs (e) quando si trascina da 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" 
+1

Non hai ancora trovato una risposta definitiva alla mia domanda, ma questo articolo è venuto più vicino: http://www.codeproject.com/Articles/28209/Outlook-Drag-and- Drop-in-C –

risposta

0

ho qui il codice sorgente di una soluzione che consente di rilascia solo articoli outlook. qui ci sono i gestori di eventi:

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(); 
     } 
    } 
+0

Esiste un motivo per cui la presenza di FileGroupDescriptor o FileGroupDescriptorW implica che l'origine era Outlook? Ci sono altre applicazioni che potrebbero avere la stessa proprietà? –

+0

non lo so, ma è qualcosa su cui devi parlare di Google. il mio esempio ha funzionato per te? –

+0

Sembra che il tuo esempio richieda un codice esterno ... OutlookDataObject? – menssana

Problemi correlati