Reputation: 23
In my C# WPF application I am sending mail using Outlook Interop. After the mail is sent, I want to retrieve it from the Sent folder for some postprocessing.
I've created the following class to encapsulate the Outlook interaction:
public class OutlookManager {
public MAPIFolder SentMailFolder { get; set; }
public Application MailApplication { get; set; }
public OutlookManager() {
MailApplication = new Application();
SentMailFolder = MailApplication.Session.GetDefaultFolder(OlDefaultFolders.olFolderSentMail);
}
}
If I use this class in a Console Application project, it works fine. The method SentMailHandler
is run when Outlook sends the email, and the subject is written in the terminal window:
private static void SentMailHandler(object item) {
var mail = (MailItem)item;
Console.WriteLine(mail.Subject);
}
private static void Main() {
OutlookManager Outlook = new OutlookManager();
Outlook.SentMailFolder.Items.ItemAdd += SentMailHandler;
MailItem mail = Outlook.MailApplication.CreateItem(OlItemType.olMailItem);
mail.To = "my-address";
mail.Subject = "Testing";
mail.Body = "This is a test";
mail.Send();
Console.Read();
}
However, when I try to incorporate the same code in my WPF application, nothing happens when the mail is sent, i.e. the SentMailHandler
method is never run, and nothing is printed in the Debug window. I have a context class MassMailContext
. An instance of this class is created and set as the DataContext
of a UI element (I am certain the constructor code is run):
internal class MassMailContext : Context {
public OutlookManager Outlook { get; set; }
public MassMailContext(MainWindow view) : base(view) {
Outlook = new OutlookManager();
Outlook.SentMailFolder.Items.ItemAdd += SentMailHandler;
MailItem mail = Outlook.MailApplication.CreateItem(OlItemType.olMailItem);
mail.To = "my-address";
mail.Subject = "Testing";
mail.Body = "This is a test";
mail.Send();
}
private void SentMailHandler(object item) {
var mail = (MailItem)item;
Console.WriteLine($"{mail.Subject}");
}
}
Note that the mail is not intended to be sent from the constructor, but is only done her for debugging purposes.
Why does it work in a Console Application project, but not in a WPF application project? The only difference I can see is, that the Main()
method of the Console Application project is still in scope when the email is sent, while this is not true for the MassMailContext
constructor.
Upvotes: 0
Views: 123
Reputation: 66255
The object raising the events (Items) must be alive to raise the events. You are setting your event handler on a temporary variable created by the compiler. As soon as it goes out of scope, it will be subject to the garbage collection.
Introduce a class member that holds the Items object and set the event handler on that variable.
Upvotes: 1