9

I’m working with WPF and I’m trying to make a drag’n’drop textbox.
In this textbox I want to get the body of an email which I drag from outlook.
The code works but I think I need something to “reset” the ActiveExplorer cause now it only shows the last “NEW” email which I drag into the textbox.

Example:

Drag email 1 -> Textbox - Shows email 1

Drag email 2 -> Textbox - Shows email 2

Drag email 1 -> Textbox - Shows email 2 and email 1 will not be displayed because it already exists in the ActiveExplorer and it will show email 2.


Hope my question is a bit clear to you..
Thanks in advance!

XAML code:

    <TextBox 
    Name="myTextbox"  
    AllowDrop="True" 
    PreviewDragEnter="email_DragEnter"
    PreviewDrop="email_Drop" />

XAML code behind:

    private void email_DragEnter(object sender, DragEventArgs e)
    {
        e.Effect = DragDropEffects.Copy;
    }

    private void email_Drop(object sender, DragEventArgs e)
    {
        Outlook.ApplicationClass oApp = new Outlook.ApplicationClass();
        Outlook.Explorer oExplorer = oApp.ActiveExplorer();
        Outlook.Selection oSelection = oExplorer.Selection;

        foreach (object item in oSelection)
        {
            Outlook.MailItem mi = (Outlook.MailItem)item;
            myTextbox.Text = mi.Body.ToString();
        }
    }
Gregoire
  • 24,219
  • 6
  • 46
  • 73
jefsmi
  • 721
  • 2
  • 9
  • 19

3 Answers3

9

I moved the declaration of oApp out of DragDrop event as below, and it works as expected.

void Startup()
{
    _Outlook = new Outlook.Application();
}

Outlook.Application _Outlook = null;

private void Form1_DragEnter(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.Copy;
}

private void Form1_DragDrop(object sender, DragEventArgs e)
{
    richTextBox1.Text = "";
    Outlook.Explorer oExplorer = _Outlook.ActiveExplorer();
    Outlook.Selection oSelection = oExplorer.Selection;

    foreach (object item in oSelection)
    {
        Outlook.MailItem mi = (Outlook.MailItem)item;
        richTextBox1.AppendText(mi.Body.ToString() + "\n----------------------------------------\n");
    }
}

--------EDIT--------

OR Is it possible that you display only the last item because of this loop?

foreach (object item in oSelection)
{
    Outlook.MailItem mi = (Outlook.MailItem)item;
    myTextbox.Text = mi.Body.ToString(); //<--- Only last items text
}
L.B
  • 114,136
  • 19
  • 178
  • 224
  • This works fine, but whats the way to get 1 email back? So only the last mail you dragged? – jefsmi Oct 21 '11 at 18:04
  • Sorry, I am not sure I understand correctly but If I drag one item, I see only it's text. If I select multiple, All of their text comes to richtextbox1 – L.B Oct 21 '11 at 18:15
  • And drag in this order: Mail 1 -> after that clear textbox and drag an Other mail -> after that clear textbox and drag Mail 1 again than it show you second dragged mail and not Mail 1 – jefsmi Oct 21 '11 at 18:22
  • 1
    Yes I did the same, and I see mail 1 not 2 :( – L.B Oct 21 '11 at 19:02
  • Can you send me a simple test project? cause it aint working here :( – jefsmi Oct 21 '11 at 19:24
  • I referenced `Microsoft Outlook 12.0 Object Library` added `using Outlook = Microsoft.Office.Interop.Outlook;` to a new form and called `Startup() in my answer`. That is all (Of course, you have to put a RichTextBox to your form). – L.B Oct 21 '11 at 19:52
  • Here is my demo sample try it ;) http://www.daangeudens.be/TestApps/EmailTestApp.rar – jefsmi Oct 21 '11 at 20:06
  • Tried several times. I don't know it is a bad news or good news but it **works**. – L.B Oct 21 '11 at 20:32
  • I tested on MS Office 2007 and it works, only on 2010 it seems to has this problem strange... – jefsmi Oct 24 '11 at 11:05
1

I updated L.B's answer. His DragEnter EventHandler automatically assumed that the user dropped in something from Outlook.

The result was that if the user dropped in something else (a file, selected text, ...), the code would still look at the currently selected emails in Outlook and ignore what was actually dropped.

The code:

Private _Outlook As Outlook.Application = Nothing

Private Sub Form_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
    _Outlook = New Outlook.Application()
End Sub

Private Sub Form_DragEnter(ByVal sender As Object, ByVal e As DragEventArgs) Handles Me.DragEnter
    Dim outlookRequiredFormats = New String() { _
        "RenPrivateSourceFolder", _
        "RenPrivateMessages", _
        "RenPrivateItem", _
        "FileGroupDescriptor", _
        "FileGroupDescriptorW", _
        "FileContents", _
        "Object Descriptor"}

    If outlookRequiredFormats.All(Function(requiredFormat) e.Data.GetDataPresent(requiredFormat)) Then
        e.Effect = DragDropEffects.Copy
    Else
        e.Effect = DragDropEffects.None
    End If
End Sub

Private Sub Form_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs) Handles Me.DragDrop
    Dim oExplorer As Outlook.Explorer = _Outlook.ActiveExplorer()
    Dim oSelection As Outlook.Selection = oExplorer.Selection
    Dim i As Integer = 0
    For Each item As Object In oSelection
        Dim mi As Outlook.MailItem = DirectCast(item, Outlook.MailItem)
        mi.SaveAs("C:\YourPath\message" & i & ".msg")
        i += 1
    Next

There is a direct cast of the selected Outlook item to Outlook.MailItem. The code thus only works with actual emails. It is also possible to handle Outlook.MeetingItem, Outlook.ContactItem, Outlook.NoteItem and probably more.

Laoujin
  • 9,962
  • 7
  • 42
  • 69
0

Using the version 14.0.0.0 of the Microsoft.Office.Interop.Outlook.dll I cannot use the Outlook.ApplicationClass object.

Instead I used the Outlook.Application in the example you gave and it works like a charm (tested with windows seven & Outlook 2007 SP2). I can drag&drop emails at will.


PS: MSDN Extract for the ApplicationClass class:

"This class supports the .NET Framework infrastructure and is not intended to be used directly from your code"

Community
  • 1
  • 1
Timothée Bourguignon
  • 2,190
  • 3
  • 23
  • 39
  • 1
    I know Outlook.ApplicationClass is embedded in version 14.0.0.0 but that ain't my question. I can drag'n'drop mails but if I drop multiple mails they are saved in the Outlook.Explorer ("like a sort of list") and I only want the mail to be shown that I drag into the textbox. At the moment the foreach goes trhough a list from the Outlook.Explorer and shows the last dropped mail and I just want my active mail to be shown. – jefsmi Oct 20 '11 at 13:49
  • Can you please precise your scenario? In the initial example you are dragging a single email whereas in your last comment you seem to mean dragging a selection of multiple emails. – Timothée Bourguignon Oct 20 '11 at 14:03
  • I'm dragging signle email's. My screnario: [#1]. Drag email_1 in textbox = OK ==> I clear textbox [#2]. Drag email_2 in textbox = OK ==> I clear textbox [#3]. Drag email_1 in textbox = NOT OK (It shows email_2). This is beceause email_2 was the last mail in the ActiveExplorer and will be the last mailItem in my foreach loop. – jefsmi Oct 20 '11 at 14:06
  • And did you try using the 'Application' class? – Timothée Bourguignon Oct 20 '11 at 14:08
  • Yes that was my first try but that didn't work so i tried with ApplicationClass and nothing changed... – jefsmi Oct 20 '11 at 14:11
  • What you describe is exactly what I do and it works perfectly and the only change I did to your snippet is the following: 'Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();' – Timothée Bourguignon Oct 20 '11 at 14:13
  • Seems strange I just tested it, and no differences here. The drag n drop works but the scenario like this [#1]. Drag email_1 in textbox = OK ==> I clear textbox [#2]. Drag email_2 in textbox = OK ==> I clear textbox [#3]. Drag email_1 in textbox = NOT OK (It shows email_2). This doesn't work how I would like it to work for me ;) – jefsmi Oct 20 '11 at 14:16
  • In which environment are you working? Which version of the MS.Office.Interop.Outlook.dll are you using? Which version of Outlook are you dragging from? – Timothée Bourguignon Oct 20 '11 at 14:21
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/4434/discussion-between-tim-bourguignon-and-degeudens) – Timothée Bourguignon Oct 21 '11 at 06:18