This project has moved and is read-only. For the latest updates, please go here.

AppointmentItem Write event never triggers

Aug 1, 2015 at 7:02 PM
Hi,

I am trying to use the AppointmentItem's Write event to give the user an option to cancel the change to a meeting in the calendar. ItemLoadCallback is called fine whenever the appointment is opened in Outlook which is what I want. I then register the Write event, but it never triggers. I have looked in OutlookSpy and the AppointmentItem does receive the event, but I just cannot figure out why event in the code below is not reached. Does anyone have any clue why?
_outlookApplication.ItemLoadEvent += new Outlook.Application_ItemLoadEventHandler(AddinLogic.ItemLoadCallback);

static Outlook.AppointmentItem _appointment = null; 

        public static void ItemLoadCallback(NetOffice.COMObject obj)
        {
            using (Outlook.AppointmentItem tmp = obj as Outlook.AppointmentItem)
            {
                if (tmp == null)
                    return;

                _appointment = tmp;
                _appointment.WriteEvent += new Outlook.AppointmentItem_WriteEventHandler(AddinLogic.AppointmentWriteEventHandler);
            }
        }

        private static void AppointmentWriteEventHandler(ref bool Cancel)
        {
// execution never gets here
            int i = 9;
        }
Aug 2, 2015 at 7:00 AM
hello hello,

you dispose the appointment item within a using statement.
the using statement is calling Dispose at the and end and this destroy all event connections for the instance-proxy.
(_appointment = tmp is not helpfull because its still the same instance.
if you dispose tmp then _appointment is also useless.)

I suggest you to remove the using statement.
optional: you can call tmp.Dispose(false) instead (may in a try/catch/finaly block)
the first argument(false) in Dispose means release the proxy but dont destroy the event connections.
(Outlook 2000 has known problems in this scenario)


*Sebastian
Aug 2, 2015 at 7:59 AM
Edited Aug 2, 2015 at 8:21 AM
Thanks! That did it. Stupid me.

Do you happen to know if there is any smart way of receiving the AppointmentItem that triggered the event from inside the AppointmentWriteEventHandler?

I see no clean option of doing it.

I have tried:
Outlook.AppointmentItem appointment = Outlook.MeetingItem.GetActiveInstance().GetAssociatedAppointment(false);
Aug 2, 2015 at 9:42 AM
hello again,

what happen? its null or wrong (exception?)

*Sebastian
Aug 2, 2015 at 10:11 AM
Outlook.MeetingItem.GetActiveInstance() returns null
Aug 2, 2015 at 4:16 PM
Edited Aug 2, 2015 at 5:28 PM
I am being referred to the links below but sure there must be a simpler way of solving this...
Do you have any clue how to best do this in NetOffice? Do I need to do something similar to the below (http://netoffice3.rssing.com/chan-15397442/all_p11.html)?
void IDTExtensibility2.OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom) {
   _outlookApplication = new Application(null, application);
   _outlookInspectors = _outlookApplication.Inspectors as Inspectors;
   
   if (_outlookInspectors != null) {
     _outlookInspectors.NewInspectorEvent += OutlookInspectorsNewInspectorEvent;
   }
}
Wenn dann ein Fenster geöffnet wird, schaue ich nach, ob es ein Mailitem ist. Wenn ja, dann füge einen Button zur standardBar hinzu
void OutlookInspectorsNewInspectorEvent(_Inspector inspector) {
  try {
    var citem = inspector.CurrentItem;
    if (citem is MailItem) {
      _standardBar = inspector.CommandBars["Standard"];

      _mBttn = (CommandBarButton)_standardBar.Controls.Add(MsoControlType.msoControlButton, 1, null, 3, true);
      _mBttn.Style = MsoButtonStyle.msoButtonIconAndCaption;
      _mBttn.FaceId = 225;  // Schloss (Icon)

      _mBttn.Caption = "Test";
      _mBttn.Tag = "MBUTTON";
      _mBttn.ClickEvent += MCmdBarBttnClickEvent;
    }
  }
}
Und zum Schluß noch der Button Event:
void MCmdBarBttnClickEvent(CommandBarButton ctrl, ref bool cancelDefault) {
  ...
  ctrl.Dispose();
}
Aug 3, 2015 at 5:25 AM
Turns out the GetActiveInstance calls actually failed due to an COMException "Target instance is not running". I passed in "true" to them.
private static void AppointmentWriteEventHandler(ref bool Cancel)
        {
            Outlook.MeetingItem m = Outlook.MeetingItem.GetActiveInstance(true);
            Outlook.AppointmentItem a = Outlook.AppointmentItem.GetActiveInstance(true);
            
            System.Windows.Forms.MessageBox.Show("Write event meeting");
        }