Why does Outlook 2007 generate 3 events for 1 single "Add"?

Status
Not open for further replies.
C

cGtlbGxleQ

Using Windows XP, running Outlook 2007, C#, Visual Studio 2005 with VSTO SE.

I have an Outlook AddIn that monitors calendar Appointments.

The AddIn is working great, but I've noticed a strange anomoly:

If I add a NEW Appointment, I expect to that my "Calendar_ItemAdd" event

handler will fire (only once).

If I change an EXISTING Appointment, I expect that my

"Calendar_ItemChange" event handler will fire (only once).

Real Behavior:

If I add a NEW Appointment, my "Calendar_ItemAdd" event handler fires (as

expected), but then my "Calendar_ItemChange" event fires 15 seconds later,

and then my "Calendar_ItemChange" event fires AGAIN, another 15 seconds later.

I'm confused. Why is Outlook 2007 calling my "Calendar_ItemChange" event

handler, when I create a single, NEW Appointment?

Here's the code that monitors the "OlDefaultFolders.olFolderCalendar" folder:

public class CalendarMonitor

{

private NameSpace m_session;

private List<string> m_folderPaths;

private List<MAPIFolder> m_calendarFolders;

private List<Items> m_calendarItems;

private List<Items> m_deletedItems;

private MAPIFolder m_deletedItemsFolder;

private MAPIFolder m_calFolder;

public event EventHandler<EventArgs<AppointmentItem>
AppointmentAdded;

public event EventHandler<EventArgs<AppointmentItem>
AppointmentModified;

public event EventHandler<CancelEventArgs<AppointmentItem>
AppointmentDeleting;

// Constructor

public CalendarMonitor(NameSpace session)

{

m_folderPaths = new List<string>();

m_calendarFolders = new List<MAPIFolder>();

m_calendarItems = new List<Items>();

m_deletedItems = new List<Items>();

m_session = session;

m_deletedItemsFolder =

session.GetDefaultFolder(OlDefaultFolders.olFolderDeletedItems);

m_calFolder =

session.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);

HookupDefaultCalendarEvents();

} // End constructor CalendarMonitor()

public void Shutdown()

{

UnhookCalendarEvents();

m_folderPaths.Clear();

m_folderPaths = null;

m_calendarFolders.Clear();

m_calendarFolders = null;

m_calendarItems.Clear();

m_calendarItems = null;

m_deletedItems.Clear();

m_deletedItems = null;

m_session = null;

m_deletedItemsFolder = null;

m_calFolder = null;

AppointmentAdded = null;

AppointmentModified = null;

AppointmentDeleting = null;

} // End Shutdown()

private void HookupDefaultCalendarEvents()

{

if ((m_calFolder != null) && (m_deletedItemsFolder != null))

{

HookupCalendarEvents();

}

} // End HookupDefaultCalendarEvents()

private void HookupCalendarEvents()

{

if (m_calFolder.DefaultItemType != OlItemType.olAppointmentItem)

{

throw new ArgumentException("The MAPIFolder 'm_calFolder'

must use AppointmentItems as the default type.");

}

// Check for duplicate entries. Helps prevent double-ups on

event listeners.

if (m_folderPaths.Contains(m_calFolder.FolderPath) == false)

{

Items items = m_calFolder.Items;

m_folderPaths.Add(m_calFolder.FolderPath);

Items delItems = m_deletedItemsFolder.Items;

// Storing a reference to the folder and to the items

collection

// keeps folder alive. This keeps the ref count up and

prevents

// the problem of intermittent release of the COM object due

to

// garbage collection, which in turn causes events to NOT

fire.

m_calendarFolders.Add(m_calFolder);

m_calendarItems.Add(items);

m_deletedItems.Add(delItems);

// Now add event listeners.

items.ItemChange +=

new

ItemsEvents_ItemChangeEventHandler(Calendar_ItemChange);

items.ItemAdd +=

new ItemsEvents_ItemAddEventHandler(Calendar_ItemAdd);

delItems.ItemAdd +=

new ItemsEvents_ItemAddEventHandler(Calendar_ItemDelete);

}

}

private void UnhookCalendarEvents()

{

foreach (Items curItem in m_calendarItems)

{

curItem.ItemChange -=

new

ItemsEvents_ItemChangeEventHandler(Calendar_ItemChange);

curItem.ItemAdd -=

new ItemsEvents_ItemAddEventHandler(Calendar_ItemAdd);

}

foreach (Items curItem in m_deletedItems)

{

curItem.ItemAdd -=

new ItemsEvents_ItemAddEventHandler(Calendar_ItemDelete);

}

}

private void Calendar_ItemAdd(object item)

{

if (item is AppointmentItem)

{

// Verify that our event handler is defined.

if (this.AppointmentAdded != null)

{

// Notify "Add" event listener.

this.AppointmentAdded(this,

new

EventArgs<AppointmentItem>((AppointmentItem)item));

}

}

}

private void Calendar_ItemChange(object item)

{

if (item is AppointmentItem)

{

// Verify that our event handler is defined.

if (this.AppointmentModified != null)

{

// Notify "Modify" event listener.

this.AppointmentModified(this,

new

EventArgs<AppointmentItem>((AppointmentItem)item));

}

}

}

private void Calendar_ItemDelete(object item)

{

if (item is AppointmentItem)

{

if (this.AppointmentDeleting != null)

{

CancelEventArgs<AppointmentItem> args =

new

CancelEventArgs<AppointmentItem>((AppointmentItem)item);

this.AppointmentDeleting(this, args);

}

}

}

} // End class CalendarMonitor

public class EventArgs<T> : EventArgs

{

private T m_value;

public EventArgs(T aValue)

{

m_value = aValue;

}

public T Value

{

get { return m_value; }

set { m_value = value; }

}

}
 
Your Delete signature is incorrect, no item is passed to tell you what was

deleted.

What exactly is being done when ItemAdd fires, are you doing anything with

that item and its properties?

"pkelley" <pkelley> wrote in message

news:F78BEA67-B35A-4F8B-B01F-986C5D8131AA@microsoft.com...
> Using Windows XP, running Outlook 2007, C#, Visual Studio 2005 with VSTO
> SE.
> I have an Outlook AddIn that monitors calendar Appointments.
> The AddIn is working great, but I've noticed a strange anomoly:

> If I add a NEW Appointment, I expect to that my "Calendar_ItemAdd" event
> handler will fire (only once).
> If I change an EXISTING Appointment, I expect that my
> "Calendar_ItemChange" event handler will fire (only once).

> Real Behavior:
> If I add a NEW Appointment, my "Calendar_ItemAdd" event handler fires
> (as
> expected), but then my "Calendar_ItemChange" event fires 15 seconds later,
> and then my "Calendar_ItemChange" event fires AGAIN, another 15 seconds
> later.

> I'm confused. Why is Outlook 2007 calling my "Calendar_ItemChange" event
> handler, when I create a single, NEW Appointment?

> Here's the code that monitors the "OlDefaultFolders.olFolderCalendar"
> folder:

> public class CalendarMonitor
> {
> private NameSpace m_session;
> private List<string> m_folderPaths;
> private List<MAPIFolder> m_calendarFolders;
> private List<Items> m_calendarItems;
> private List<Items> m_deletedItems;
> private MAPIFolder m_deletedItemsFolder;
> private MAPIFolder m_calFolder;
> public event EventHandler<EventArgs<AppointmentItem>
> AppointmentAdded;
> public event EventHandler<EventArgs<AppointmentItem>
> AppointmentModified;
> public event EventHandler<CancelEventArgs<AppointmentItem>
> AppointmentDeleting;

> // Constructor
> public CalendarMonitor(NameSpace session)
> {
> m_folderPaths = new List<string>();
> m_calendarFolders = new List<MAPIFolder>();
> m_calendarItems = new List<Items>();
> m_deletedItems = new List<Items>();
> m_session = session;
> m_deletedItemsFolder =
> session.GetDefaultFolder(OlDefaultFolders.olFolderDeletedItems);
> m_calFolder =
> session.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
> HookupDefaultCalendarEvents();
> } // End constructor CalendarMonitor()

> public void Shutdown()
> {
> UnhookCalendarEvents();
> m_folderPaths.Clear();
> m_folderPaths = null;
> m_calendarFolders.Clear();
> m_calendarFolders = null;
> m_calendarItems.Clear();
> m_calendarItems = null;
> m_deletedItems.Clear();
> m_deletedItems = null;
> m_session = null;
> m_deletedItemsFolder = null;
> m_calFolder = null;
> AppointmentAdded = null;
> AppointmentModified = null;
> AppointmentDeleting = null;
> } // End Shutdown()

> private void HookupDefaultCalendarEvents()
> {
> if ((m_calFolder != null) && (m_deletedItemsFolder != null))
> {
> HookupCalendarEvents();
> }
> } // End HookupDefaultCalendarEvents()

> private void HookupCalendarEvents()
> {
> if (m_calFolder.DefaultItemType !=
> OlItemType.olAppointmentItem)
> {
> throw new ArgumentException("The MAPIFolder 'm_calFolder'
> must use AppointmentItems as the default type.");
> }

> // Check for duplicate entries. Helps prevent double-ups on
> event listeners.
> if (m_folderPaths.Contains(m_calFolder.FolderPath) == false)
> {
> Items items = m_calFolder.Items;
> m_folderPaths.Add(m_calFolder.FolderPath);

> Items delItems = m_deletedItemsFolder.Items;

> // Storing a reference to the folder and to the items
> collection
> // keeps folder alive. This keeps the ref count up and
> prevents
> // the problem of intermittent release of the COM object
> due
> to
> // garbage collection, which in turn causes events to NOT
> fire.
> m_calendarFolders.Add(m_calFolder);
> m_calendarItems.Add(items);
> m_deletedItems.Add(delItems);

> // Now add event listeners.
> items.ItemChange +=
> new
> ItemsEvents_ItemChangeEventHandler(Calendar_ItemChange);
> items.ItemAdd +=
> new ItemsEvents_ItemAddEventHandler(Calendar_ItemAdd);
> delItems.ItemAdd +=
> new
> ItemsEvents_ItemAddEventHandler(Calendar_ItemDelete);
> }
> }

> private void UnhookCalendarEvents()
> {
> foreach (Items curItem in m_calendarItems)
> {
> curItem.ItemChange -=
> new
> ItemsEvents_ItemChangeEventHandler(Calendar_ItemChange);
> curItem.ItemAdd -=
> new ItemsEvents_ItemAddEventHandler(Calendar_ItemAdd);
> }
> foreach (Items curItem in m_deletedItems)
> {
> curItem.ItemAdd -=
> new
> ItemsEvents_ItemAddEventHandler(Calendar_ItemDelete);
> }
> }

> private void Calendar_ItemAdd(object item)
> {
> if (item is AppointmentItem)
> {
> // Verify that our event handler is defined.
> if (this.AppointmentAdded != null)
> {
> // Notify "Add" event listener.
> this.AppointmentAdded(this,
> new
> EventArgs<AppointmentItem>((AppointmentItem)item));
> }
> }
> }

> private void Calendar_ItemChange(object item)
> {
> if (item is AppointmentItem)
> {
> // Verify that our event handler is defined.
> if (this.AppointmentModified != null)
> {
> // Notify "Modify" event listener.
> this.AppointmentModified(this,
> new
> EventArgs<AppointmentItem>((AppointmentItem)item));
> }
> }
> }

> private void Calendar_ItemDelete(object item)
> {
> if (item is AppointmentItem)
> {
> if (this.AppointmentDeleting != null)
> {
> CancelEventArgs<AppointmentItem> args =
> new
> CancelEventArgs<AppointmentItem>((AppointmentItem)item);
> this.AppointmentDeleting(this, args);
> }
> }
> }
> } // End class CalendarMonitor

> public class EventArgs<T> : EventArgs
> {
> private T m_value;

> public EventArgs(T aValue)
> {
> m_value = aValue;
> }

> public T Value
> {
> get { return m_value; }
> set { m_value = value; }
> }
> }
>
 
Why are you suprised? Something modifies an item after it is created...

Dmitry Streblechenko (MVP)

-

"pkelley" <pkelley> wrote in message

news:F78BEA67-B35A-4F8B-B01F-986C5D8131AA@microsoft.com...
> Using Windows XP, running Outlook 2007, C#, Visual Studio 2005 with VSTO
> SE.
> I have an Outlook AddIn that monitors calendar Appointments.
> The AddIn is working great, but I've noticed a strange anomoly:

> If I add a NEW Appointment, I expect to that my "Calendar_ItemAdd" event
> handler will fire (only once).
> If I change an EXISTING Appointment, I expect that my
> "Calendar_ItemChange" event handler will fire (only once).

> Real Behavior:
> If I add a NEW Appointment, my "Calendar_ItemAdd" event handler fires
> (as
> expected), but then my "Calendar_ItemChange" event fires 15 seconds later,
> and then my "Calendar_ItemChange" event fires AGAIN, another 15 seconds
> later.

> I'm confused. Why is Outlook 2007 calling my "Calendar_ItemChange" event
> handler, when I create a single, NEW Appointment?

> Here's the code that monitors the "OlDefaultFolders.olFolderCalendar"
> folder:

> public class CalendarMonitor
> {
> private NameSpace m_session;
> private List<string> m_folderPaths;
> private List<MAPIFolder> m_calendarFolders;
> private List<Items> m_calendarItems;
> private List<Items> m_deletedItems;
> private MAPIFolder m_deletedItemsFolder;
> private MAPIFolder m_calFolder;
> public event EventHandler<EventArgs<AppointmentItem>
> AppointmentAdded;
> public event EventHandler<EventArgs<AppointmentItem>
> AppointmentModified;
> public event EventHandler<CancelEventArgs<AppointmentItem>
> AppointmentDeleting;

> // Constructor
> public CalendarMonitor(NameSpace session)
> {
> m_folderPaths = new List<string>();
> m_calendarFolders = new List<MAPIFolder>();
> m_calendarItems = new List<Items>();
> m_deletedItems = new List<Items>();
> m_session = session;
> m_deletedItemsFolder =
> session.GetDefaultFolder(OlDefaultFolders.olFolderDeletedItems);
> m_calFolder =
> session.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
> HookupDefaultCalendarEvents();
> } // End constructor CalendarMonitor()

> public void Shutdown()
> {
> UnhookCalendarEvents();
> m_folderPaths.Clear();
> m_folderPaths = null;
> m_calendarFolders.Clear();
> m_calendarFolders = null;
> m_calendarItems.Clear();
> m_calendarItems = null;
> m_deletedItems.Clear();
> m_deletedItems = null;
> m_session = null;
> m_deletedItemsFolder = null;
> m_calFolder = null;
> AppointmentAdded = null;
> AppointmentModified = null;
> AppointmentDeleting = null;
> } // End Shutdown()

> private void HookupDefaultCalendarEvents()
> {
> if ((m_calFolder != null) && (m_deletedItemsFolder != null))
> {
> HookupCalendarEvents();
> }
> } // End HookupDefaultCalendarEvents()

> private void HookupCalendarEvents()
> {
> if (m_calFolder.DefaultItemType !=
> OlItemType.olAppointmentItem)
> {
> throw new ArgumentException("The MAPIFolder 'm_calFolder'
> must use AppointmentItems as the default type.");
> }

> // Check for duplicate entries. Helps prevent double-ups on
> event listeners.
> if (m_folderPaths.Contains(m_calFolder.FolderPath) == false)
> {
> Items items = m_calFolder.Items;
> m_folderPaths.Add(m_calFolder.FolderPath);

> Items delItems = m_deletedItemsFolder.Items;

> // Storing a reference to the folder and to the items
> collection
> // keeps folder alive. This keeps the ref count up and
> prevents
> // the problem of intermittent release of the COM object
> due
> to
> // garbage collection, which in turn causes events to NOT
> fire.
> m_calendarFolders.Add(m_calFolder);
> m_calendarItems.Add(items);
> m_deletedItems.Add(delItems);

> // Now add event listeners.
> items.ItemChange +=
> new
> ItemsEvents_ItemChangeEventHandler(Calendar_ItemChange);
> items.ItemAdd +=
> new ItemsEvents_ItemAddEventHandler(Calendar_ItemAdd);
> delItems.ItemAdd +=
> new
> ItemsEvents_ItemAddEventHandler(Calendar_ItemDelete);
> }
> }

> private void UnhookCalendarEvents()
> {
> foreach (Items curItem in m_calendarItems)
> {
> curItem.ItemChange -=
> new
> ItemsEvents_ItemChangeEventHandler(Calendar_ItemChange);
> curItem.ItemAdd -=
> new ItemsEvents_ItemAddEventHandler(Calendar_ItemAdd);
> }
> foreach (Items curItem in m_deletedItems)
> {
> curItem.ItemAdd -=
> new
> ItemsEvents_ItemAddEventHandler(Calendar_ItemDelete);
> }
> }

> private void Calendar_ItemAdd(object item)
> {
> if (item is AppointmentItem)
> {
> // Verify that our event handler is defined.
> if (this.AppointmentAdded != null)
> {
> // Notify "Add" event listener.
> this.AppointmentAdded(this,
> new
> EventArgs<AppointmentItem>((AppointmentItem)item));
> }
> }
> }

> private void Calendar_ItemChange(object item)
> {
> if (item is AppointmentItem)
> {
> // Verify that our event handler is defined.
> if (this.AppointmentModified != null)
> {
> // Notify "Modify" event listener.
> this.AppointmentModified(this,
> new
> EventArgs<AppointmentItem>((AppointmentItem)item));
> }
> }
> }

> private void Calendar_ItemDelete(object item)
> {
> if (item is AppointmentItem)
> {
> if (this.AppointmentDeleting != null)
> {
> CancelEventArgs<AppointmentItem> args =
> new
> CancelEventArgs<AppointmentItem>((AppointmentItem)item);
> this.AppointmentDeleting(this, args);
> }
> }
> }
> } // End class CalendarMonitor

> public class EventArgs<T> : EventArgs
> {
> private T m_value;

> public EventArgs(T aValue)
> {
> m_value = aValue;
> }

> public T Value
> {
> get { return m_value; }
> set { m_value = value; }
> }
> }
>
 
With regard to Delete:

In the constructor method "CalendarMonitor" I get a handle to the deleted

items folder.

Then in "HookupCalendarEvents()" I'm trying to handle the ItemAdd event of

the deleted

items folder so whenever an item is moved to the deleted items folder the

"Calendar_ItemDelete" event

handler fires and "Calendar_ItemDelete" is passed the item added to the

delete folder.

Also, in the constructor "CalendarMonitor" I get a handle to the calendar

folder.

Then in "HookupCalendarEvents()" I handle the ItemAdd and ItemChange events

of the calendar

folder.

In all three cases, Calendar_ItemChange, Calendar_ItemAdd,

Calendar_ItemDelete seem to receive

the proper Item for processing. Do you still see something I'm missing? If

yes, what would you

do to handle the ItemAdd event to the deleted items folder?

With regard to the ItemAdd Event, the Event Handlers are in my "ThisAddIn"

class:

public partial class ThisAddIn

{

#region Instance Variables

private Outlook.Inspectors m_Inspectors; // Outlook

inspectors collection

private Outlook.NameSpace m_nameSpace;

internal static List<OutlookInspector> m_Windows; // List of tracked

inspector windows

internal static Office.IRibbonUI m_Ribbon; // Ribbon UI

reference

private CalendarMonitor m_monitor; // Calendar

appointment events.

private Outlook.AppointmentItem m_olAppointment;

#endregion

#region VSTO Startup and Shutdown methods

private void ThisAddIn_Startup(object sender, System.EventArgs e)

{

// Initialize variables

m_Inspectors = this.Application.Inspectors;

m_nameSpace = this.Application.GetNamespace("MAPI");

m_Windows = new List<OutlookInspector>();

m_monitor = new CalendarMonitor(this.Application.Session);

// Wire up event handlers

m_monitor.AppointmentAdded +=

new

EventHandler<EventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentAdded);

m_monitor.AppointmentDeleting +=

new

EventHandler<CancelEventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentDeleting);

m_monitor.AppointmentModified +=

new

EventHandler<EventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentModified);

m_Inspectors.NewInspector +=

new

Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);

}

private void ThisAddIn_Shutdown(object sender, System.EventArgs e)

{

// Unhook event handlers

if (m_odbcForm != null)

{

m_odbcForm.ODBCConnectionStatus -=

new

EventHandler<EventArgs<bool>>(SetODBCConnectionStatus);

}

m_monitor.AppointmentAdded -=

new

EventHandler<EventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentAdded);

m_monitor.AppointmentDeleting -=

new

EventHandler<CancelEventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentDeleting);

m_monitor.AppointmentModified -=

new

EventHandler<EventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentModified);

m_monitor.Shutdown();

m_odbcForm.FormShutdown();

m_Inspectors.NewInspector -= new

Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);

// Dereference objects

m_Inspectors = null;

m_Windows.Clear();

m_Windows = null;

m_Ribbon = null;

m_nameSpace = null;

m_monitor = null;

m_olAppointment = null;

}

#endregion

#region Methods

/// <summary
/// Looks up the window wrapper for a given window object

/// </summary
/// <param name="window">An outlook inspector window</param
/// <returns></returns
internal static OutlookInspector FindOutlookInspector(object window)

{

foreach (OutlookInspector inspector in m_Windows)

{

if (inspector.Window == window)

{

return inspector;

}

}

return null;

}

/// <summary
/// Iterates through a list of Appointment "Outlook.Recipients" and

/// has Microsoft Exchange identify their SMTP email addresses.

/// This routine then concatenates the email address to the end of a

/// string and separates each email address using a semi-colon ";"

/// followed by a space " " character.

/// The returned string is trimmed of spaces (and tabs) leaving a

/// string containing email addresses separated and terminated by

/// a semi-colon ";"

/// </summary
/// <param name="recipients">A collection of Recipient

objects.</param
/// <returns>A string object containing Appointment Attendee email

addresses.

/// For Example:

/// "myEmail@company.com; hisEmail@company.com;

etcEmail@company.com;"

/// </returns
private string

GetAttendees(Microsoft.Office.Interop.Outlook.Recipients recipients)

{

string attendees = null;

Microsoft.Office.Interop.Outlook.ExchangeUser exUser = null;

string smtpAddr = null;

foreach (Microsoft.Office.Interop.Outlook.Recipient recipient in

recipients)

{

exUser = recipient.AddressEntry.GetExchangeUser();

if (exUser == null)

{

smtpAddr = recipient.Address;

}

else

{

smtpAddr = exUser.PrimarySmtpAddress;

}

attendees += (smtpAddr + "; ");

}

if (attendees != null)

return attendees.Trim();

else

return "none@dtint.com;";

}

private string GetFromEMailAddress(string fromName)

{

string emailAddr = "none@dti.com";

Outlook.Recipient recip = m_nameSpace.CreateRecipient(fromName);

Outlook.ExchangeUser exchgUser =

recip.AddressEntry.GetExchangeUser();

if (exchgUser != null)

{

emailAddr = exchgUser.PrimarySmtpAddress;

}

return emailAddr;

}

#endregion

#region Event Handlers

private void SetODBCConnectionStatus(object sender, EventArgs<bool
connected)

{

m_odbcIsActive = connected.Value;

if (m_ribbon != null)

{

m_ribbon.SetConnectedToDB(m_odbcIsActive);

}

}

private void Monitor_AppointmentAdded(object sender,

EventArgs<Outlook.AppointmentItem> appt)

{

string formatStr;

string msg;

if (m_ribbon.isDTIAssignment())

{

if ((appt.Value.Subject != null) && (appt.Value.Location !=

null))

{

string dbAction = "NEW";

string attendees = GetAttendees(appt.Value.Recipients);

string fromEMailAddr =

GetFromEMailAddress(appt.Value.Organizer);

m_odbcForm.Do_eBudgetSQL(dbAction,

appt.Value.Subject, appt.Value.Location,

fromEMailAddr,

attendees, appt.Value.StartUTC.ToString(),

appt.Value.EndUTC.ToString(),

appt.Value.Body);

}

else

{

formatStr = "DTI Appointments require Subject and

Location. ADD to Cache ignored.";

msg = System.String.Format(formatStr,

appt.Value.Subject);

MessageBox.Show(msg);

}

}

}

private void Monitor_AppointmentDeleting(object sender,

CancelEventArgs<Outlook.AppointmentItem> appt)

{

string formatStr;

string msg;

if (m_ribbon.isDTIAssignment())

{

if ((appt.Value.Subject != null) && (appt.Value.Location !=

null))

{

string dbAction = "DELETE";

string attendees = GetAttendees(appt.Value.Recipients);

string fromEMailAddr =

GetFromEMailAddress(appt.Value.Organizer);

m_odbcForm.Do_eBudgetSQL(dbAction,

appt.Value.Subject, appt.Value.Location,

fromEMailAddr,

attendees, appt.Value.StartUTC.ToString(),

appt.Value.EndUTC.ToString(),

appt.Value.Body);

}

else

{

formatStr = "DTI Appointments require Subject and

Location. DELETE from Cache ignored.";

msg = System.String.Format(formatStr,

appt.Value.Subject);

MessageBox.Show(msg);

}

}

// We could prevent the delete from happening if we wanted to,

// but we don't so allow the delete to occur.

appt.Cancel = false;

}

/// <summary
/// This method is called immediately following the "Add" event of

/// a Calendar AppointmentItem.

/// This method is also called immediately following the

"Modification"

/// event of a Calendar AppointmentItem.

/// </summary
/// <param name="sender">The sending object</param
/// <param name="appt">The calendar appointment record

modified</param
private void Monitor_AppointmentModified(object sender,

EventArgs<Outlook.AppointmentItem> appt)

{

string formatStr;

string msg;

if (m_ribbon.isDTIAssignment())

{

if ((appt.Value.Subject != null) && (appt.Value.Location !=

null))

{

string dbAction = "CHANGE";

string attendees = GetAttendees(appt.Value.Recipients);

string fromEMailAddr =

GetFromEMailAddress(appt.Value.Organizer);

m_odbcForm.Do_eBudgetSQL(dbAction,

appt.Value.Subject, appt.Value.Location,

fromEMailAddr,

attendees, appt.Value.StartUTC.ToString(),

appt.Value.EndUTC.ToString(),

appt.Value.Body);

}

else

{

formatStr = "DTI Appointments require Subject and

Location. CHANGE Cache value ignored.";

msg = System.String.Format(formatStr,

appt.Value.Subject);

MessageBox.Show(msg);

}

}

}

/// <summary
/// The NewInspector event fires whenever a new inspector is

displayed. We use

/// this event to add our custom button to appointment item

inspectors.

/// </summary
/// <param name="Inspector"></param
private void Inspectors_NewInspector(Outlook.Inspector Inspector)

{

try

{

// Debug.WriteLine("Inspectors_NewInspector");

OutlookItem olItem = new OutlookItem(Inspector.CurrentItem);

// Make sure this is an appointment item

if (olItem.Class == Outlook.OlObjectClass.olAppointment)

{

m_olAppointment =

(Outlook.AppointmentItem)Inspector.CurrentItem;

m_ribbon.setApptItem(m_olAppointment);

// Check to see if this is a new window

// we don't already track

OutlookInspector existingWindow =

FindOutlookInspector(Inspector);

// If the m_Windows collection does not

// have a window for this Inspector,

// we should add it to m_Windows

if (existingWindow == null)

{

OutlookInspector window = new

OutlookInspector(Inspector);

window.Close += new EventHandler(WrappedWindow_Close);

window.InvalidateControl +=

new

EventHandler<EventArgs<string>>(WrappedWindow_InvalidateControl);

m_Windows.Add(window);

}

}

}

catch (Exception ex)

{

Debug.WriteLine(ex.Message);

}

}

void WrappedWindow_InvalidateControl(object sender,

EventArgs<string> e)

{

if (m_Ribbon != null)

{

m_Ribbon.InvalidateControl(e.Value);

}

}

void WrappedWindow_Close(object sender, EventArgs e)

{

OutlookInspector window = (OutlookInspector)sender;

window.Close -= new EventHandler(WrappedWindow_Close);

m_Windows.Remove(window);

}

#endregion

#region VSTO generated code

/// <summary
/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

/// </summary
private void InternalStartup()

{

this.Startup += new System.EventHandler(ThisAddIn_Startup);

this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);

}

#endregion

}
wrote:


> Your Delete signature is incorrect, no item is passed to tell you what was
> deleted.

> What exactly is being done when ItemAdd fires, are you doing anything with
> that item and its properties?

> >

>

> "pkelley" <pkelley> wrote in message
> news:F78BEA67-B35A-4F8B-B01F-986C5D8131AA@microsoft.com...
> > Using Windows XP, running Outlook 2007, C#, Visual Studio 2005 with VSTO
> > SE.
> > I have an Outlook AddIn that monitors calendar Appointments.
> > The AddIn is working great, but I've noticed a strange anomoly:
> > If I add a NEW Appointment, I expect to that my "Calendar_ItemAdd" event
> > handler will fire (only once).
> > If I change an EXISTING Appointment, I expect that my
> > "Calendar_ItemChange" event handler will fire (only once).
> > Real Behavior:
> > If I add a NEW Appointment, my "Calendar_ItemAdd" event handler fires
> > (as
> > expected), but then my "Calendar_ItemChange" event fires 15 seconds later,
> > and then my "Calendar_ItemChange" event fires AGAIN, another 15 seconds
> > later.
> > I'm confused. Why is Outlook 2007 calling my "Calendar_ItemChange" event
> > handler, when I create a single, NEW Appointment?
> > Here's the code that monitors the "OlDefaultFolders.olFolderCalendar"
> > folder:
> > public class CalendarMonitor
> > {
> > private NameSpace m_session;
> > private List<string> m_folderPaths;
> > private List<MAPIFolder> m_calendarFolders;
> > private List<Items> m_calendarItems;
> > private List<Items> m_deletedItems;
> > private MAPIFolder m_deletedItemsFolder;
> > private MAPIFolder m_calFolder;
> > public event EventHandler<EventArgs<AppointmentItem>
> > AppointmentAdded;
> > public event EventHandler<EventArgs<AppointmentItem>
> > AppointmentModified;
> > public event EventHandler<CancelEventArgs<AppointmentItem>
> > AppointmentDeleting;
> > // Constructor
> > public CalendarMonitor(NameSpace session)
> > {
> > m_folderPaths = new List<string>();
> > m_calendarFolders = new List<MAPIFolder>();
> > m_calendarItems = new List<Items>();
> > m_deletedItems = new List<Items>();
> > m_session = session;
> > m_deletedItemsFolder =
> > session.GetDefaultFolder(OlDefaultFolders.olFolderDeletedItems);
> > m_calFolder =
> > session.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
> > HookupDefaultCalendarEvents();
> > } // End constructor CalendarMonitor()
> > public void Shutdown()
> > {
> > UnhookCalendarEvents();
> > m_folderPaths.Clear();
> > m_folderPaths = null;
> > m_calendarFolders.Clear();
> > m_calendarFolders = null;
> > m_calendarItems.Clear();
> > m_calendarItems = null;
> > m_deletedItems.Clear();
> > m_deletedItems = null;
> > m_session = null;
> > m_deletedItemsFolder = null;
> > m_calFolder = null;
> > AppointmentAdded = null;
> > AppointmentModified = null;
> > AppointmentDeleting = null;
> > } // End Shutdown()
> > private void HookupDefaultCalendarEvents()
> > {
> > if ((m_calFolder != null) && (m_deletedItemsFolder != null))
> > {
> > HookupCalendarEvents();
> > }
> > } // End HookupDefaultCalendarEvents()
> > private void HookupCalendarEvents()
> > {
> > if (m_calFolder.DefaultItemType !=
> > OlItemType.olAppointmentItem)
> > {
> > throw new ArgumentException("The MAPIFolder 'm_calFolder'
> > must use AppointmentItems as the default type.");
> > }
> > // Check for duplicate entries. Helps prevent double-ups on
> > event listeners.
> > if (m_folderPaths.Contains(m_calFolder.FolderPath) == false)
> > {
> > Items items = m_calFolder.Items;
> > m_folderPaths.Add(m_calFolder.FolderPath);
> > Items delItems = m_deletedItemsFolder.Items;
> > // Storing a reference to the folder and to the items
> > collection
> > // keeps folder alive. This keeps the ref count up and
> > prevents
> > // the problem of intermittent release of the COM object
> > due
> > to
> > // garbage collection, which in turn causes events to NOT
> > fire.
> > m_calendarFolders.Add(m_calFolder);
> > m_calendarItems.Add(items);
> > m_deletedItems.Add(delItems);
> > // Now add event listeners.
> > items.ItemChange +=
> > new
> > ItemsEvents_ItemChangeEventHandler(Calendar_ItemChange);
> > items.ItemAdd +=
> > new ItemsEvents_ItemAddEventHandler(Calendar_ItemAdd);
> > delItems.ItemAdd +=
> > new
> > ItemsEvents_ItemAddEventHandler(Calendar_ItemDelete);
> > }
> > }
> > private void UnhookCalendarEvents()
> > {
> > foreach (Items curItem in m_calendarItems)
> > {
> > curItem.ItemChange -=
> > new
> > ItemsEvents_ItemChangeEventHandler(Calendar_ItemChange);
> > curItem.ItemAdd -=
> > new ItemsEvents_ItemAddEventHandler(Calendar_ItemAdd);
> > }
> > foreach (Items curItem in m_deletedItems)
> > {
> > curItem.ItemAdd -=
> > new
> > ItemsEvents_ItemAddEventHandler(Calendar_ItemDelete);
> > }
> > }
> > private void Calendar_ItemAdd(object item)
> > {
> > if (item is AppointmentItem)
> > {
> > // Verify that our event handler is defined.
> > if (this.AppointmentAdded != null)
> > {
> > // Notify "Add" event listener.
> > this.AppointmentAdded(this,
> > new
> > EventArgs<AppointmentItem>((AppointmentItem)item));
> > }
> > }
> > }
> > private void Calendar_ItemChange(object item)
> > {
> > if (item is AppointmentItem)
> > {
> > // Verify that our event handler is defined.
> > if (this.AppointmentModified != null)
> > {
> > // Notify "Modify" event listener.
> > this.AppointmentModified(this,
> > new
> > EventArgs<AppointmentItem>((AppointmentItem)item));
> > }
> > }
> > }
> > private void Calendar_ItemDelete(object item)
> > {
> > if (item is AppointmentItem)
> > {
> > if (this.AppointmentDeleting != null)
> > {
> > CancelEventArgs<AppointmentItem> args =
> > new
> > CancelEventArgs<AppointmentItem>((AppointmentItem)item);
> > this.AppointmentDeleting(this, args);
> > }
> > }
> > }
> > } // End class CalendarMonitor
> > public class EventArgs<T> : EventArgs
> > {
> > private T m_value;
> > public EventArgs(T aValue)
> > {
> > m_value = aValue;
> > }
> > public T Value
> > {
> > get { return m_value; }
> > set { m_value = value; }
> > }
> > }
> >


>
 
Just seems strang that within 15 seconds of the initial ADD, I get two

modifications to the item. I guess if the modification to the item is due to

some time-stamp being posted by Exchange, I can understand that. It would

make sense.

"Dmitry Streblechenko" wrote:


> Why are you suprised? Something modifies an item after it is created...
> > Dmitry Streblechenko (MVP)
>

>

>

> -
> "pkelley" <pkelley> wrote in message
> news:F78BEA67-B35A-4F8B-B01F-986C5D8131AA@microsoft.com...
> > Using Windows XP, running Outlook 2007, C#, Visual Studio 2005 with VSTO
> > SE.
> > I have an Outlook AddIn that monitors calendar Appointments.
> > The AddIn is working great, but I've noticed a strange anomoly:
> > If I add a NEW Appointment, I expect to that my "Calendar_ItemAdd" event
> > handler will fire (only once).
> > If I change an EXISTING Appointment, I expect that my
> > "Calendar_ItemChange" event handler will fire (only once).
> > Real Behavior:
> > If I add a NEW Appointment, my "Calendar_ItemAdd" event handler fires
> > (as
> > expected), but then my "Calendar_ItemChange" event fires 15 seconds later,
> > and then my "Calendar_ItemChange" event fires AGAIN, another 15 seconds
> > later.
> > I'm confused. Why is Outlook 2007 calling my "Calendar_ItemChange" event
> > handler, when I create a single, NEW Appointment?
> > Here's the code that monitors the "OlDefaultFolders.olFolderCalendar"
> > folder:
> > public class CalendarMonitor
> > {
> > private NameSpace m_session;
> > private List<string> m_folderPaths;
> > private List<MAPIFolder> m_calendarFolders;
> > private List<Items> m_calendarItems;
> > private List<Items> m_deletedItems;
> > private MAPIFolder m_deletedItemsFolder;
> > private MAPIFolder m_calFolder;
> > public event EventHandler<EventArgs<AppointmentItem>
> > AppointmentAdded;
> > public event EventHandler<EventArgs<AppointmentItem>
> > AppointmentModified;
> > public event EventHandler<CancelEventArgs<AppointmentItem>
> > AppointmentDeleting;
> > // Constructor
> > public CalendarMonitor(NameSpace session)
> > {
> > m_folderPaths = new List<string>();
> > m_calendarFolders = new List<MAPIFolder>();
> > m_calendarItems = new List<Items>();
> > m_deletedItems = new List<Items>();
> > m_session = session;
> > m_deletedItemsFolder =
> > session.GetDefaultFolder(OlDefaultFolders.olFolderDeletedItems);
> > m_calFolder =
> > session.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
> > HookupDefaultCalendarEvents();
> > } // End constructor CalendarMonitor()
> > public void Shutdown()
> > {
> > UnhookCalendarEvents();
> > m_folderPaths.Clear();
> > m_folderPaths = null;
> > m_calendarFolders.Clear();
> > m_calendarFolders = null;
> > m_calendarItems.Clear();
> > m_calendarItems = null;
> > m_deletedItems.Clear();
> > m_deletedItems = null;
> > m_session = null;
> > m_deletedItemsFolder = null;
> > m_calFolder = null;
> > AppointmentAdded = null;
> > AppointmentModified = null;
> > AppointmentDeleting = null;
> > } // End Shutdown()
> > private void HookupDefaultCalendarEvents()
> > {
> > if ((m_calFolder != null) && (m_deletedItemsFolder != null))
> > {
> > HookupCalendarEvents();
> > }
> > } // End HookupDefaultCalendarEvents()
> > private void HookupCalendarEvents()
> > {
> > if (m_calFolder.DefaultItemType !=
> > OlItemType.olAppointmentItem)
> > {
> > throw new ArgumentException("The MAPIFolder 'm_calFolder'
> > must use AppointmentItems as the default type.");
> > }
> > // Check for duplicate entries. Helps prevent double-ups on
> > event listeners.
> > if (m_folderPaths.Contains(m_calFolder.FolderPath) == false)
> > {
> > Items items = m_calFolder.Items;
> > m_folderPaths.Add(m_calFolder.FolderPath);
> > Items delItems = m_deletedItemsFolder.Items;
> > // Storing a reference to the folder and to the items
> > collection
> > // keeps folder alive. This keeps the ref count up and
> > prevents
> > // the problem of intermittent release of the COM object
> > due
> > to
> > // garbage collection, which in turn causes events to NOT
> > fire.
> > m_calendarFolders.Add(m_calFolder);
> > m_calendarItems.Add(items);
> > m_deletedItems.Add(delItems);
> > // Now add event listeners.
> > items.ItemChange +=
> > new
> > ItemsEvents_ItemChangeEventHandler(Calendar_ItemChange);
> > items.ItemAdd +=
> > new ItemsEvents_ItemAddEventHandler(Calendar_ItemAdd);
> > delItems.ItemAdd +=
> > new
> > ItemsEvents_ItemAddEventHandler(Calendar_ItemDelete);
> > }
> > }
> > private void UnhookCalendarEvents()
> > {
> > foreach (Items curItem in m_calendarItems)
> > {
> > curItem.ItemChange -=
> > new
> > ItemsEvents_ItemChangeEventHandler(Calendar_ItemChange);
> > curItem.ItemAdd -=
> > new ItemsEvents_ItemAddEventHandler(Calendar_ItemAdd);
> > }
> > foreach (Items curItem in m_deletedItems)
> > {
> > curItem.ItemAdd -=
> > new
> > ItemsEvents_ItemAddEventHandler(Calendar_ItemDelete);
> > }
> > }
> > private void Calendar_ItemAdd(object item)
> > {
> > if (item is AppointmentItem)
> > {
> > // Verify that our event handler is defined.
> > if (this.AppointmentAdded != null)
> > {
> > // Notify "Add" event listener.
> > this.AppointmentAdded(this,
> > new
> > EventArgs<AppointmentItem>((AppointmentItem)item));
> > }
> > }
> > }
> > private void Calendar_ItemChange(object item)
> > {
> > if (item is AppointmentItem)
> > {
> > // Verify that our event handler is defined.
> > if (this.AppointmentModified != null)
> > {
> > // Notify "Modify" event listener.
> > this.AppointmentModified(this,
> > new
> > EventArgs<AppointmentItem>((AppointmentItem)item));
> > }
> > }
> > }
> > private void Calendar_ItemDelete(object item)
> > {
> > if (item is AppointmentItem)
> > {
> > if (this.AppointmentDeleting != null)
> > {
> > CancelEventArgs<AppointmentItem> args =
> > new
> > CancelEventArgs<AppointmentItem>((AppointmentItem)item);
> > this.AppointmentDeleting(this, args);
> > }
> > }
> > }
> > } // End class CalendarMonitor
> > public class EventArgs<T> : EventArgs
> > {
> > private T m_value;
> > public EventArgs(T aValue)
> > {
> > m_value = aValue;
> > }
> > public T Value
> > {
> > get { return m_value; }
> > set { m_value = value; }
> > }
> > }
> >


>
 
I'm not going to even try analyzing all that code.

ItemAdd() provides you with an item, as does ItemChange(), ItemRemove() does

not. If what you were doing was adding an ItemAdd() handler for Deleted

Items then I misread your code, if it was an ItemRemove() event handler no

item would be supplied.

"pkelley" <pkelley> wrote in message

news:32D5569A-8519-4A72-AE5D-7A6B768DDFA8@microsoft.com...
> With regard to Delete:

> In the constructor method "CalendarMonitor" I get a handle to the deleted
> items folder.
> Then in "HookupCalendarEvents()" I'm trying to handle the ItemAdd event
> of
> the deleted
> items folder so whenever an item is moved to the deleted items folder the
> "Calendar_ItemDelete" event
> handler fires and "Calendar_ItemDelete" is passed the item added to the
> delete folder.

> Also, in the constructor "CalendarMonitor" I get a handle to the calendar
> folder.
> Then in "HookupCalendarEvents()" I handle the ItemAdd and ItemChange
> events
> of the calendar
> folder.

> In all three cases, Calendar_ItemChange, Calendar_ItemAdd,
> Calendar_ItemDelete seem to receive
> the proper Item for processing. Do you still see something I'm missing?
> If
> yes, what would you
> do to handle the ItemAdd event to the deleted items folder?

> With regard to the ItemAdd Event, the Event Handlers are in my "ThisAddIn"
> class:

> public partial class ThisAddIn
> {
> #region Instance Variables

> private Outlook.Inspectors m_Inspectors; // Outlook
> inspectors collection
> private Outlook.NameSpace m_nameSpace;
> internal static List<OutlookInspector> m_Windows; // List of
> tracked
> inspector windows
> internal static Office.IRibbonUI m_Ribbon; // Ribbon UI
> reference
> private CalendarMonitor m_monitor; // Calendar
> appointment events.
> private Outlook.AppointmentItem m_olAppointment;

> #endregion

> #region VSTO Startup and Shutdown methods

> private void ThisAddIn_Startup(object sender, System.EventArgs e)
> {
> // Initialize variables
> m_Inspectors = this.Application.Inspectors;
> m_nameSpace = this.Application.GetNamespace("MAPI");
> m_Windows = new List<OutlookInspector>();
> m_monitor = new CalendarMonitor(this.Application.Session);

> // Wire up event handlers
> m_monitor.AppointmentAdded +=
> new
> EventHandler<EventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentAdded);
> m_monitor.AppointmentDeleting +=
> new
> EventHandler<CancelEventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentDeleting);
> m_monitor.AppointmentModified +=
> new
> EventHandler<EventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentModified);
> m_Inspectors.NewInspector +=
> new
> Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);
> }

> private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
> {
> // Unhook event handlers
> if (m_odbcForm != null)
> {
> m_odbcForm.ODBCConnectionStatus -=
> new
> EventHandler<EventArgs<bool>>(SetODBCConnectionStatus);
> }
> m_monitor.AppointmentAdded -=
> new
> EventHandler<EventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentAdded);
> m_monitor.AppointmentDeleting -=
> new
> EventHandler<CancelEventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentDeleting);
> m_monitor.AppointmentModified -=
> new
> EventHandler<EventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentModified);
> m_monitor.Shutdown();
> m_odbcForm.FormShutdown();
> m_Inspectors.NewInspector -= new
> Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);

> // Dereference objects
> m_Inspectors = null;
> m_Windows.Clear();
> m_Windows = null;
> m_Ribbon = null;
> m_nameSpace = null;
> m_monitor = null;
> m_olAppointment = null;
> }

> #endregion

> #region Methods

> /// <summary
> /// Looks up the window wrapper for a given window object
> /// </summary
> /// <param name="window">An outlook inspector window</param
> /// <returns></returns
> internal static OutlookInspector FindOutlookInspector(object
> window)
> {
> foreach (OutlookInspector inspector in m_Windows)
> {
> if (inspector.Window == window)
> {
> return inspector;
> }
> }
> return null;
> }

> /// <summary
> /// Iterates through a list of Appointment "Outlook.Recipients" and
> /// has Microsoft Exchange identify their SMTP email addresses.
> /// This routine then concatenates the email address to the end of
> a
> /// string and separates each email address using a semi-colon ";"
> /// followed by a space " " character.
> /// The returned string is trimmed of spaces (and tabs) leaving a
> /// string containing email addresses separated and terminated by
> /// a semi-colon ";"
> /// </summary
> /// <param name="recipients">A collection of Recipient
> objects.</param
> /// <returns>A string object containing Appointment Attendee email
> addresses.
> /// For Example:
> /// "myEmail@company.com; hisEmail@company.com;
> etcEmail@company.com;"
> /// </returns
> private string
> GetAttendees(Microsoft.Office.Interop.Outlook.Recipients recipients)
> {
> string attendees = null;
> Microsoft.Office.Interop.Outlook.ExchangeUser exUser = null;
> string smtpAddr = null;
> foreach (Microsoft.Office.Interop.Outlook.Recipient recipient
> in
> recipients)
> {
> exUser = recipient.AddressEntry.GetExchangeUser();
> if (exUser == null)
> {
> smtpAddr = recipient.Address;
> }
> else
> {
> smtpAddr = exUser.PrimarySmtpAddress;
> }
> attendees += (smtpAddr + "; ");
> }
> if (attendees != null)
> return attendees.Trim();
> else
> return "none@dtint.com;";
> }

> private string GetFromEMailAddress(string fromName)
> {
> string emailAddr = "none@dti.com";
> Outlook.Recipient recip =
> m_nameSpace.CreateRecipient(fromName);
> Outlook.ExchangeUser exchgUser =
> recip.AddressEntry.GetExchangeUser();
> if (exchgUser != null)
> {
> emailAddr = exchgUser.PrimarySmtpAddress;
> }
> return emailAddr;
> }

> #endregion

> #region Event Handlers

> private void SetODBCConnectionStatus(object sender, EventArgs<bool
> connected)
> {
> m_odbcIsActive = connected.Value;
> if (m_ribbon != null)
> {
> m_ribbon.SetConnectedToDB(m_odbcIsActive);
> }
> }

> private void Monitor_AppointmentAdded(object sender,
> EventArgs<Outlook.AppointmentItem> appt)
> {
> string formatStr;
> string msg;

> if (m_ribbon.isDTIAssignment())
> {
> if ((appt.Value.Subject != null) && (appt.Value.Location !=
> null))
> {
> string dbAction = "NEW";
> string attendees = GetAttendees(appt.Value.Recipients);
> string fromEMailAddr =
> GetFromEMailAddress(appt.Value.Organizer);
> m_odbcForm.Do_eBudgetSQL(dbAction,
> appt.Value.Subject, appt.Value.Location,
> fromEMailAddr,
> attendees, appt.Value.StartUTC.ToString(),
> appt.Value.EndUTC.ToString(),
> appt.Value.Body);
> }
> else
> {
> formatStr = "DTI Appointments require Subject and
> Location. ADD to Cache ignored.";
> msg = System.String.Format(formatStr,
> appt.Value.Subject);
> MessageBox.Show(msg);
> }
> }
> }

> private void Monitor_AppointmentDeleting(object sender,
> CancelEventArgs<Outlook.AppointmentItem> appt)
> {
> string formatStr;
> string msg;

> if (m_ribbon.isDTIAssignment())
> {
> if ((appt.Value.Subject != null) && (appt.Value.Location !=
> null))
> {
> string dbAction = "DELETE";
> string attendees = GetAttendees(appt.Value.Recipients);
> string fromEMailAddr =
> GetFromEMailAddress(appt.Value.Organizer);
> m_odbcForm.Do_eBudgetSQL(dbAction,
> appt.Value.Subject, appt.Value.Location,
> fromEMailAddr,
> attendees, appt.Value.StartUTC.ToString(),
> appt.Value.EndUTC.ToString(),
> appt.Value.Body);
> }
> else
> {
> formatStr = "DTI Appointments require Subject and
> Location. DELETE from Cache ignored.";
> msg = System.String.Format(formatStr,
> appt.Value.Subject);
> MessageBox.Show(msg);
> }
> }

> // We could prevent the delete from happening if we wanted to,
> // but we don't so allow the delete to occur.
> appt.Cancel = false;
> }

> /// <summary
> /// This method is called immediately following the "Add" event of
> /// a Calendar AppointmentItem.
> /// This method is also called immediately following the
> "Modification"
> /// event of a Calendar AppointmentItem.
> /// </summary
> /// <param name="sender">The sending object</param
> /// <param name="appt">The calendar appointment record
> modified</param
> private void Monitor_AppointmentModified(object sender,
> EventArgs<Outlook.AppointmentItem> appt)
> {
> string formatStr;
> string msg;

> if (m_ribbon.isDTIAssignment())
> {
> if ((appt.Value.Subject != null) && (appt.Value.Location !=
> null))
> {
> string dbAction = "CHANGE";
> string attendees = GetAttendees(appt.Value.Recipients);
> string fromEMailAddr =
> GetFromEMailAddress(appt.Value.Organizer);
> m_odbcForm.Do_eBudgetSQL(dbAction,
> appt.Value.Subject, appt.Value.Location,
> fromEMailAddr,
> attendees, appt.Value.StartUTC.ToString(),
> appt.Value.EndUTC.ToString(),
> appt.Value.Body);
> }
> else
> {
> formatStr = "DTI Appointments require Subject and
> Location. CHANGE Cache value ignored.";
> msg = System.String.Format(formatStr,
> appt.Value.Subject);
> MessageBox.Show(msg);
> }
> }
> }

> /// <summary
> /// The NewInspector event fires whenever a new inspector is
> displayed. We use
> /// this event to add our custom button to appointment item
> inspectors.
> /// </summary
> /// <param name="Inspector"></param
> private void Inspectors_NewInspector(Outlook.Inspector Inspector)
> {
> try
> {
> // Debug.WriteLine("Inspectors_NewInspector");
> OutlookItem olItem = new
> OutlookItem(Inspector.CurrentItem);

> // Make sure this is an appointment item
> if (olItem.Class == Outlook.OlObjectClass.olAppointment)
> {
> m_olAppointment =
> (Outlook.AppointmentItem)Inspector.CurrentItem;
> m_ribbon.setApptItem(m_olAppointment);

> // Check to see if this is a new window
> // we don't already track
> OutlookInspector existingWindow =
> FindOutlookInspector(Inspector);
> // If the m_Windows collection does not
> // have a window for this Inspector,
> // we should add it to m_Windows
> if (existingWindow == null)
> {
> OutlookInspector window = new
> OutlookInspector(Inspector);
> window.Close += new
> EventHandler(WrappedWindow_Close);
> window.InvalidateControl +=
> new
> EventHandler<EventArgs<string>>(WrappedWindow_InvalidateControl);
> m_Windows.Add(window);
> }

> }
> }
> catch (Exception ex)
> {
> Debug.WriteLine(ex.Message);
> }
> }

> void WrappedWindow_InvalidateControl(object sender,
> EventArgs<string> e)
> {
> if (m_Ribbon != null)
> {
> m_Ribbon.InvalidateControl(e.Value);
> }
> }

> void WrappedWindow_Close(object sender, EventArgs e)
> {
> OutlookInspector window = (OutlookInspector)sender;
> window.Close -= new EventHandler(WrappedWindow_Close);
> m_Windows.Remove(window);
> }

> #endregion

> #region VSTO generated code

> /// <summary
> /// Required method for Designer support - do not modify
> /// the contents of this method with the code editor.
> /// </summary
> private void InternalStartup()
> {
> this.Startup += new System.EventHandler(ThisAddIn_Startup);
> this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
> }

> #endregion
> }
>
 
Sorry for overwhelming you with too much code. I get a little intense

sometimes.

I was trying to answer your question, "What exactly is being done when

ItemAdd fires, are you doing anything with that item and its properties?"

The code shows it all.

Anyway, thank you for spending some time on this. You have been helpful.
wrote:


> I'm not going to even try analyzing all that code.

> ItemAdd() provides you with an item, as does ItemChange(), ItemRemove() does
> not. If what you were doing was adding an ItemAdd() handler for Deleted
> Items then I misread your code, if it was an ItemRemove() event handler no
> item would be supplied.

> >

>

> "pkelley" <pkelley> wrote in message
> news:32D5569A-8519-4A72-AE5D-7A6B768DDFA8@microsoft.com...
> > With regard to Delete:
> > In the constructor method "CalendarMonitor" I get a handle to the deleted
> > items folder.
> > Then in "HookupCalendarEvents()" I'm trying to handle the ItemAdd event
> > of
> > the deleted
> > items folder so whenever an item is moved to the deleted items folder the
> > "Calendar_ItemDelete" event
> > handler fires and "Calendar_ItemDelete" is passed the item added to the
> > delete folder.
> > Also, in the constructor "CalendarMonitor" I get a handle to the calendar
> > folder.
> > Then in "HookupCalendarEvents()" I handle the ItemAdd and ItemChange
> > events
> > of the calendar
> > folder.
> > In all three cases, Calendar_ItemChange, Calendar_ItemAdd,
> > Calendar_ItemDelete seem to receive
> > the proper Item for processing. Do you still see something I'm missing?
> > If
> > yes, what would you
> > do to handle the ItemAdd event to the deleted items folder?
> > With regard to the ItemAdd Event, the Event Handlers are in my "ThisAddIn"
> > class:
> > public partial class ThisAddIn
> > {
> > #region Instance Variables
> > private Outlook.Inspectors m_Inspectors; // Outlook
> > inspectors collection
> > private Outlook.NameSpace m_nameSpace;
> > internal static List<OutlookInspector> m_Windows; // List of
> > tracked
> > inspector windows
> > internal static Office.IRibbonUI m_Ribbon; // Ribbon UI
> > reference
> > private CalendarMonitor m_monitor; // Calendar
> > appointment events.
> > private Outlook.AppointmentItem m_olAppointment;
> > #endregion
> > #region VSTO Startup and Shutdown methods
> > private void ThisAddIn_Startup(object sender, System.EventArgs e)
> > {
> > // Initialize variables
> > m_Inspectors = this.Application.Inspectors;
> > m_nameSpace = this.Application.GetNamespace("MAPI");
> > m_Windows = new List<OutlookInspector>();
> > m_monitor = new CalendarMonitor(this.Application.Session);
> > // Wire up event handlers
> > m_monitor.AppointmentAdded +=
> > new
> > EventHandler<EventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentAdded);
> > m_monitor.AppointmentDeleting +=
> > new
> > EventHandler<CancelEventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentDeleting);
> > m_monitor.AppointmentModified +=
> > new
> > EventHandler<EventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentModified);
> > m_Inspectors.NewInspector +=
> > new
> > Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);
> > }
> > private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
> > {
> > // Unhook event handlers
> > if (m_odbcForm != null)
> > {
> > m_odbcForm.ODBCConnectionStatus -=
> > new
> > EventHandler<EventArgs<bool>>(SetODBCConnectionStatus);
> > }
> > m_monitor.AppointmentAdded -=
> > new
> > EventHandler<EventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentAdded);
> > m_monitor.AppointmentDeleting -=
> > new
> > EventHandler<CancelEventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentDeleting);
> > m_monitor.AppointmentModified -=
> > new
> > EventHandler<EventArgs<Microsoft.Office.Interop.Outlook.AppointmentItem>>(Monitor_AppointmentModified);
> > m_monitor.Shutdown();
> > m_odbcForm.FormShutdown();
> > m_Inspectors.NewInspector -= new
> > Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);
> > // Dereference objects
> > m_Inspectors = null;
> > m_Windows.Clear();
> > m_Windows = null;
> > m_Ribbon = null;
> > m_nameSpace = null;
> > m_monitor = null;
> > m_olAppointment = null;
> > }
> > #endregion
> > #region Methods
> > /// <summary
> > /// Looks up the window wrapper for a given window object
> > /// </summary
> > /// <param name="window">An outlook inspector window</param
> > /// <returns></returns
> > internal static OutlookInspector FindOutlookInspector(object
> > window)
> > {
> > foreach (OutlookInspector inspector in m_Windows)
> > {
> > if (inspector.Window == window)
> > {
> > return inspector;
> > }
> > }
> > return null;
> > }
> > /// <summary
> > /// Iterates through a list of Appointment "Outlook.Recipients" and
> > /// has Microsoft Exchange identify their SMTP email addresses.
> > /// This routine then concatenates the email address to the end of
> > a
> > /// string and separates each email address using a semi-colon ";"
> > /// followed by a space " " character.
> > /// The returned string is trimmed of spaces (and tabs) leaving a
> > /// string containing email addresses separated and terminated by
> > /// a semi-colon ";"
> > /// </summary
> > /// <param name="recipients">A collection of Recipient
> > objects.</param
> > /// <returns>A string object containing Appointment Attendee email
> > addresses.
> > /// For Example:
> > /// "myEmail@company.com; hisEmail@company.com;
> > etcEmail@company.com;"
> > /// </returns
> > private string
> > GetAttendees(Microsoft.Office.Interop.Outlook.Recipients recipients)
> > {
> > string attendees = null;
> > Microsoft.Office.Interop.Outlook.ExchangeUser exUser = null;
> > string smtpAddr = null;
> > foreach (Microsoft.Office.Interop.Outlook.Recipient recipient
> > in
> > recipients)
> > {
> > exUser = recipient.AddressEntry.GetExchangeUser();
> > if (exUser == null)
> > {
> > smtpAddr = recipient.Address;
> > }
> > else
> > {
> > smtpAddr = exUser.PrimarySmtpAddress;
> > }
> > attendees += (smtpAddr + "; ");
> > }
> > if (attendees != null)
> > return attendees.Trim();
> > else
> > return "none@dtint.com;";
> > }
> > private string GetFromEMailAddress(string fromName)
> > {
> > string emailAddr = "none@dti.com";
> > Outlook.Recipient recip =
> > m_nameSpace.CreateRecipient(fromName);
> > Outlook.ExchangeUser exchgUser =
> > recip.AddressEntry.GetExchangeUser();
> > if (exchgUser != null)
> > {
> > emailAddr = exchgUser.PrimarySmtpAddress;
> > }
> > return emailAddr;
> > }
> > #endregion
> > #region Event Handlers
> > private void SetODBCConnectionStatus(object sender, EventArgs<bool
> > connected)
> > {
> > m_odbcIsActive = connected.Value;
> > if (m_ribbon != null)
> > {
> > m_ribbon.SetConnectedToDB(m_odbcIsActive);
> > }
> > }
> > private void Monitor_AppointmentAdded(object sender,
> > EventArgs<Outlook.AppointmentItem> appt)
> > {
> > string formatStr;
> > string msg;
> > if (m_ribbon.isDTIAssignment())
> > {
> > if ((appt.Value.Subject != null) && (appt.Value.Location !=
> > null))
> > {
> > string dbAction = "NEW";
> > string attendees = GetAttendees(appt.Value.Recipients);
> > string fromEMailAddr =
> > GetFromEMailAddress(appt.Value.Organizer);
> > m_odbcForm.Do_eBudgetSQL(dbAction,
> > appt.Value.Subject, appt.Value.Location,
> > fromEMailAddr,
> > attendees, appt.Value.StartUTC.ToString(),
> > appt.Value.EndUTC.ToString(),
> > appt.Value.Body);
> > }
> > else
> > {
> > formatStr = "DTI Appointments require Subject and
> > Location. ADD to Cache ignored.";
> > msg = System.String.Format(formatStr,
> > appt.Value.Subject);
> > MessageBox.Show(msg);
> > }
> > }
> > }
> > private void Monitor_AppointmentDeleting(object sender,
> > CancelEventArgs<Outlook.AppointmentItem> appt)
> > {
> > string formatStr;
> > string msg;
> > if (m_ribbon.isDTIAssignment())
> > {
> > if ((appt.Value.Subject != null) && (appt.Value.Location !=
> > null))
> > {
> > string dbAction = "DELETE";
> > string attendees = GetAttendees(appt.Value.Recipients);
> > string fromEMailAddr =
> > GetFromEMailAddress(appt.Value.Organizer);
> > m_odbcForm.Do_eBudgetSQL(dbAction,
> > appt.Value.Subject, appt.Value.Location,
> > fromEMailAddr,
> > attendees, appt.Value.StartUTC.ToString(),
> > appt.Value.EndUTC.ToString(),
> > appt.Value.Body);
> > }
> > else
> > {
> > formatStr = "DTI Appointments require Subject and
> > Location. DELETE from Cache ignored.";
> > msg = System.String.Format(formatStr,
> > appt.Value.Subject);
> > MessageBox.Show(msg);
> > }
> > }
> > // We could prevent the delete from happening if we wanted to,
> > // but we don't so allow the delete to occur.
> > appt.Cancel = false;
> > }
> > /// <summary
> > /// This method is called immediately following the "Add" event of
> > /// a Calendar AppointmentItem.
> > /// This method is also called immediately following the
> > "Modification"
> > /// event of a Calendar AppointmentItem.
> > /// </summary
> > /// <param name="sender">The sending object</param
> > /// <param name="appt">The calendar appointment record
> > modified</param>
 
Status
Not open for further replies.
Similar threads
Thread starter Title Forum Replies Date
L Outlook 2007 does not start with Apple iCloud-Add-In activated Using Outlook 2
K Outlook 2007 Calendar - Time spinner does not function correctly Using Outlook 1
E Double clicking on from email address does no longer open corresponding contact in Outlook 2007 Using Outlook 7
B Importing Contacts Does Not Use Defined Custom Form in Outlook 2007 Outlook VBA and Custom Forms 1
G What does 'daily limit has been reached' mean in Outlook 2007? BCM (Business Contact Manager) 1
H Where does Outlook 2007 save the default reminder settings? Outlook VBA and Custom Forms 1
B Outlook 2007 Custom Form does not display in 2003 Outlook VBA and Custom Forms 3
M "Attachment Detacher for Outlook" add in, does it update the server copy of the email? Using Outlook 1
J Event/Meeting in Outlook Does Not Align with SharePoint Calendar Using Outlook 5
C Why does Outlook (desktop) 365 for Windows keep making me input my passwords? Using Outlook 12
V Outlook 2016 Does Outlook-2016 (64 bit) work with iCloud for Windows ? Using Outlook 5
T Why does outlook 2010 convert only some forum notifications to plain text? Using Outlook 0
M Outlook .com group does not show up in Outlook for office 365 home Using Outlook 3
W Outlook Calendar does not save view any longer! Using Outlook 3
B Outlook 2016 Does not Shutdown Correctly Using Outlook 3
P Desktop doesn't index Outlook IMAP files, laptop Outlook does index those same IMAP files Using Outlook 2
J Outlook 2016 message content does not display - outlook.com; exchange Using Outlook.com accounts in Outlook 9
D Outlook 2016 IMAP Connection Returns All Email but outlook.com does NOT Using Outlook.com accounts in Outlook 2
D Outlook 2016: /altvba startup switch does not work Using Outlook 2
S Outlook does not open the .pst file created by the Outlook Using Outlook 5
O Windows 10 x64 Outlook 2013 - URL does not open (anymore) Using Outlook 3
M How does Outlook determine item numbers in a folder? Outlook VBA and Custom Forms 3
C Unchecking "Send immediately when connected" does not work on apps that call Outlook Using Outlook 1
J Outlook 2010 VBScript editor does not run code at all Outlook VBA and Custom Forms 0
G Outlook does not show new appointments in To-Do-Bar Using Outlook 0
C bcm 2010 download does not recognize outlook Using Outlook 3
A Does Outlook import Gmail Archive? Using Outlook 1
1Firefly Outlook 2013 Converstation preview does not show my last reply Exchange Server Administration 1
T outlook 2013 does not mark multiple forward messages as forward Using Outlook 2
C Outlook 2013 - Email Gets Sent - But Does Not Move From Outbox to Sent Box Using Outlook 4
M does outlook 2013/365 on mac support custom forms? Outlook VBA and Custom Forms 1
H Outlook.com calendar does not update from Outlook 2013 Home Premium Using Outlook 1
M Incoming invites to my imap account does not sync to outlook.com Using Outlook.com accounts in Outlook 29
S Outlook 2013 To Do Task does not minimize. Using Outlook 0
D Outlook 2013 deletes emails, does not send them to Deleted Items or Trash Using Outlook 2
O Outlook 2010 does not open MS Word attachments Using Outlook 1
A File - Save Attachments does nothing in Outlook 2003 with Exchange 2010 ... Using Outlook 3
M Outlook Appointment item does not show the item outside the date range Using Outlook 2
H Reocurring outlook appointment (office 2010) does not update Outlook.com Using Outlook 3
F Outlook 2010 contact e-mail Display as: does not show contact name Using Outlook 2
P Reply All does not work in Outlook 2010 Cached mode Using Outlook 4
R Outlook 2013 does not show in default programs - how do I search Using Outlook 1
U How does outlook desktop work with outlook.com Using Outlook 5
V Outlook Calendar No Reminders Show up but does on iPhone Using Outlook 0
V Outlook Calendar No Reminders Show up but does on iPhone Using Outlook 2
Fozzie Bear How does Outlook 2003 deals with IMAP configuration Using Outlook 8
J Does Outlook 2003 run on Windows 8 Professional? Using Outlook 2
E Does Outlook indexing work across multiple servers? Using Outlook 0
E Does Outlook 2010 support searching multiple .pst files simultaneously? Using Outlook 0
J Outlook 2003 does not send or receive imap mail from server Using Outlook 0

Similar threads

Back
Top