Получить текст из электронной почты Outlook [Drag’n’Drop]

Я работаю с WPF и пытаюсь создать текстовое поле с перетаскиванием.
В этом текстовом поле я хочу получить тело письма, которое я перетаскиваю из Outlook.
Код работает, но я думаю, что мне нужно что-то, чтобы «сбросить» ActiveExplorer, потому что теперь он показывает только последнее «НОВОЕ» электронное письмо, которое я перетаскиваю в текстовое поле.

Пример:

Перетащите электронную почту 1 -> Текстовое поле — показывает электронную почту 1

Перетащите электронное письмо 2 -> Текстовое поле — показывает электронное письмо 2

Перетащите электронную почту 1 -> Текстовое поле — показывает электронную почту 2, а электронная почта 1 не будет отображаться, потому что она уже существует в ActiveExplorer, и она покажет электронную почту 2.


Надеюсь, мой вопрос вам немного ясен..
Заранее спасибо!

XAML-код:

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

Код XAML позади:

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

person jefsmi    schedule 18.10.2011    source источник


Ответы (3)


Я переместил объявление oApp из события DragDrop, как показано ниже, и оно работает, как и ожидалось.

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");
    }
}

--------РЕДАКТИРОВАТЬ--------

ИЛИ Возможно ли, что вы отображаете только последний элемент из-за этого цикла?

foreach (object item in oSelection)
{
    Outlook.MailItem mi = (Outlook.MailItem)item;
    myTextbox.Text = mi.Body.ToString(); //<--- Only last items text
}
person L.B    schedule 20.10.2011
comment
Это прекрасно работает, но как вернуть 1 электронное письмо? Так только последнюю почту ты таскал? - person jefsmi; 21.10.2011
comment
Извините, я не уверен, что правильно понял, но если я перетащу один элемент, я увижу только его текст. Если я выберу несколько, весь их текст попадет в richtextbox1 - person L.B; 21.10.2011
comment
И перетащите в следующем порядке: Почта 1 -> после этого очистите текстовое поле и перетащите другую почту -> после этого очистите текстовое поле и снова перетащите Почта 1, чтобы показать вам вторую перетаскиваемую почту, а не Почту 1. - person jefsmi; 21.10.2011
comment
Да, я сделал то же самое, и я вижу почту 1, а не 2 :( - person L.B; 21.10.2011
comment
Можете ли вы прислать мне простой тестовый проект? потому что здесь не работает :( - person jefsmi; 21.10.2011
comment
Я сослался на Microsoft Outlook 12.0 Object Library, добавил using Outlook = Microsoft.Office.Interop.Outlook; в новую форму и назвал Startup() in my answer. Это все (конечно, вы должны поместить RichTextBox в свою форму). - person L.B; 21.10.2011
comment
Вот мой демо-пример, попробуйте ;) daangeudens.be/TestApps/EmailTestApp.rar - person jefsmi; 22.10.2011
comment
Пробовал несколько раз. Не знаю, плохие это новости или хорошие, но это работает. - person L.B; 22.10.2011
comment
Я тестировал на MS Office 2007, и он работает, только в 2010 году эта проблема кажется странной... - person jefsmi; 24.10.2011

Я обновил ответ LB. Его DragEnter EventHandler автоматически предположил, что пользователь добавил что-то из Outlook.

В результате, если пользователь вставлял что-то еще (файл, выделенный текст и т. д.), код все равно просматривал выбранные в данный момент электронные письма в Outlook и игнорировал то, что на самом деле было удалено.

Код:

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

Существует прямое приведение выбранного элемента Outlook к Outlook.MailItem. Таким образом, код работает только с реальными электронными письмами. Также можно обрабатывать Outlook.MeetingItem, Outlook.ContactItem, Outlook.NoteItem и, возможно, больше.

person Laoujin    schedule 22.06.2012

Используя версию 14.0.0.0 Microsoft.Office.Interop.Outlook.dll, я не могу использовать объект Outlook.ApplicationClass.

Вместо этого я использовал Outlook.Application в приведенном вами примере, и он работает как шарм (протестировано с Windows 7 и Outlook 2007 SP2). Я могу перетаскивать электронные письма по желанию.


PS: Извлечение MSDN для класса ApplicationClass:

Этот класс поддерживает инфраструктуру .NET Framework и не предназначен для непосредственного использования в вашем коде

person Timothée Bourguignon    schedule 20.10.2011
comment
Я знаю, что Outlook.ApplicationClass встроен в версию 14.0.0.0, но это не мой вопрос. Я могу перетаскивать почту, но если я удаляю несколько писем, они сохраняются в Outlook.Explorer (как своего рода список), и я хочу, чтобы отображалась только та почта, которую я перетаскиваю в текстовое поле. На данный момент foreach проходит через список из Outlook.Explorer и показывает последнюю удаленную почту, и я просто хочу, чтобы моя активная почта отображалась. - person jefsmi; 20.10.2011
comment
Не могли бы вы уточнить свой сценарий? В начальном примере вы перетаскиваете одно электронное письмо, тогда как в своем последнем комментарии вы, кажется, имеете в виду перетаскивание нескольких электронных писем. - person Timothée Bourguignon; 20.10.2011
comment
Я перетаскиваю электронные письма. Мой сценарий: [#1]. Перетащите email_1 в текстовое поле = OK ==> Я очищаю текстовое поле [#2]. Перетащите email_2 в текстовое поле = OK ==> Я очищаю текстовое поле [#3]. Перетащите адрес электронной почты_1 в текстовое поле = НЕ ОК (отображается адрес электронной почты_2). Это потому, что email_2 был последним письмом в ActiveExplorer и будет последним mailItem в моем цикле foreach. - person jefsmi; 20.10.2011
comment
А вы пробовали использовать класс «Приложение»? - person Timothée Bourguignon; 20.10.2011
comment
Да, это была моя первая попытка, но она не сработала, поэтому я попробовал ApplicationClass, и ничего не изменилось... - person jefsmi; 20.10.2011
comment
То, что вы описываете, это именно то, что я делаю, и это работает отлично, и единственное изменение, которое я внес в ваш фрагмент, заключается в следующем: «Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application(); ' - person Timothée Bourguignon; 20.10.2011
comment
Кажется странным, я только что проверил это, и здесь нет никаких различий. Перетаскивание работает, но сценарий такой [#1]. Перетащите email_1 в текстовое поле = OK ==> Я очищаю текстовое поле [#2]. Перетащите email_2 в текстовое поле = OK ==> Я очищаю текстовое поле [#3]. Перетащите адрес электронной почты_1 в текстовое поле = НЕ ОК (отображается адрес электронной почты_2). Это не работает так, как я хотел бы, чтобы это работало для меня;) - person jefsmi; 20.10.2011
comment
В какой среде вы работаете? Какую версию MS.Office.Interop.Outlook.dll вы используете? Из какой версии Outlook вы перетаскиваете? - person Timothée Bourguignon; 20.10.2011
comment
давайте продолжим это обсуждение в чате - person Timothée Bourguignon; 21.10.2011