Appointment Propertycahnge event fires many times when we add attendess RRS feed

  • Question

  • Hi,

    i have devolved a com addin running on oulook 2010(14.0.7012.1000) SP2.  i have code in the addin which will monitor whenever attendess are added or removed from meeting in the inspector window. it build a list of attendess evrytime it finds that there is change in previous saved list and that happens when you add or remove attendee

    What i found is that adding or removing an attendee action fires property change event many times and its requiredattendee and optionalateendee and resources property which is being changed many times. when i was debugging it, i found some of the already existing attendee were added and removed from recipients object many times, so, for example if i have added 4 ateendee and then removing one was firing propertychnage event many times and each time recipient count was coming different, sometimee it comes out to 2 and then 1 and then agian 2 and then again 3.  i am anot sure about the exact pattern because everytime it was different.

    The firing of the event may vary depending  on how many attendees are there and this repetition is making my addin slow at this stage. let me know if this is how it suppose to work or if there is any problem in the code.

    Here is my code.

    Assume AppItem has been initialised already and is of appointment type

    ItemOpen and RoomBookingPage are true.

    The NAR function will release com object

    Private Sub AppItem_PropertyChange(ByVal Name As String) Handles AppItem.PropertyChange If (ItemOpen And RoomBookingPage) Then 'Pass relevant changes to the web page Case "OptionalAttendees", "RequiredAttendees" Dim AttendeeList As String = GetRecipients() If Attendees <> AttendeeList Then SetPageProperty(Browser, "attendees", AttendeeList) Attendees = AttendeeList End If

    End Select

    End if End Sub Public Function GetRecipients(Optional ByVal IsUrlString = False) As String Dim strRecipients As String = "" strRecipients = GetOutlookRecipients(IsUrlString) GetRecipients = strRecipients End Function Public Function GetOutlookRecipients(ByVal UrlString As Boolean) As String Dim strRecipients As String = "[" Dim strNameAddress As String Dim Recipients As Outlook.Recipients = Nothing Dim RecipientIndex As Integer = 1 Dim Count As Integer Try Recipients = AppItem.Recipients Count = Recipients.Count() Dim recipient As Outlook.Recipient = Nothing If Count > 0 Then Do While RecipientIndex <= Count recipient = Recipients(RecipientIndex) strNameAddress = GetRecipientAddress(recipient, IsUrlString:=UrlString) NAR(recipient) If strRecipients <> "[" Then strRecipients = strRecipients & "," strRecipients = strRecipients & strNameAddress RecipientIndex = RecipientIndex + 1 Loop End If Catch ex As System.Exception strRecipients = "[" End Try GetOutlookRecipients = strRecipients & "]" Log("GetOutlookRecipients : " & GetOutlookRecipients) NAR(Recipients) End Function Public Function GetRecipientAddress(ByVal Recipient As Outlook.Recipient, Optional ByVal AddressOnly As Boolean = False, Optional ByVal IsUrlString As Boolean = False) As String Dim Name As String = Recipient.Name Dim Address As String = Recipient.Address GetRecipientAddress = "" Recipient.Resolve() If (Address Is Nothing) Then 'try one more time to get Address, some how expression at prvious try was not evaluted Address = Recipient.Address End If If Recipient.Resolved Then Dim AddressEntry As AddressEntry = Recipient.AddressEntry Log("GetRecipientAddress: AddressEntry type " + AddressEntry.AddressEntryUserType.ToString) Select Case AddressEntry.AddressEntryUserType Case OlAddressEntryUserType.olSmtpAddressEntry Case OlAddressEntryUserType.olExchangeUserAddressEntry, OlAddressEntryUserType.olExchangeRemoteUserAddressEntry Log("GetRecipientAddress: Member of olExchangeUserAddressEntry or olExchangeRemoteUserAddressEntry") Dim oEU As Outlook.ExchangeUser = AddressEntry.GetExchangeUser If Not (oEU Is Nothing) Then Address = oEU.PrimarySmtpAddress End If NAR(oEU) Case OlAddressEntryUserType.olExchangeDistributionListAddressEntry Log("GetRecipientAddress: Member of olExchangeDistributionListAddressEntry") Dim oEDL As Outlook.ExchangeDistributionList = AddressEntry.GetExchangeDistributionList If Not (oEDL Is Nothing) Then Dim Members As Outlook.AddressEntries = oEDL.GetExchangeDistributionListMembers Dim Member As Outlook.AddressEntry Dim oEU As Outlook.ExchangeUser Dim i As Integer For i = 1 To Members.Count Member = Members(i) oEU = Member.GetExchangeUser If AddressOnly Then GetRecipientAddress = GetRecipientAddress & oEU.PrimarySmtpAddress & "," Else GetRecipientAddress = GetRecipientAddress & "{name: \""" & oEU.LastName & "," & oEU.FirstName & "\"", address: \""" & oEU.PrimarySmtpAddress & "\""}," End If NAR(Member) NAR(oEU) Next i GetRecipientAddress = Left(GetRecipientAddress, Len(GetRecipientAddress) - 1) NAR(Members) Else Log("GetRecipientAddress: cannot resolve ExchangeDistributionList") End If NAR(oEDL) End Select Else Log("GetRecipientAddress: Recipient failed to resolve") End If Log("GetRecipientAddress: In GetRecipient Addrees " + GetRecipientAddress) If GetRecipientAddress = "" Then If AddressOnly Then GetRecipientAddress = Address Else If (IsUrlString) Then Name = Replace(Replace(EscapeDataString(Name), "%5C", "%5C%5C%5C%5C"), "%22", "%5C%5c%5c%22") Else 'MsgBox(Chr(22)) Name = Replace(Replace(Name, "\", "\\\\"), ControlChars.Quote, "\\\" + ControlChars.Quote) End If If (Address Is Nothing) Then Address = Name ElseIf (IsUrlString) Then Address = Replace(Replace(EscapeDataString(Address), "%5C", "%5C%5C%5C%5C"), "%22", "%5C%5c%5c%22") Else Address = Replace(Replace(Address, "\", "\\\\"), ControlChars.Quote, "\\\" + ControlChars.Quote) End If GetRecipientAddress = "{name: \""" & Name & "\"", address: \""" & Address & "\""}" End If End If End Function Private Sub NAR(ByRef o As Object) Dim Count As Integer = 1 Try 'While Count > 0 Count = System.Runtime.InteropServices.Marshal.ReleaseComObject(o) 'Log("Released object: count=" & Count) 'End While Catch Finally o = Nothing End Try End Sub

    • Edited by Nitrup Friday, June 20, 2014 10:01 AM code change
    Friday, June 20, 2014 10:00 AM


All replies

  • Hello Nytrup,

    The PropertyChange event is fired for each property separately. You need to check the passed parameter and handle the event further or skip the process. It is normal that the event is fired multiple times for separate proerties when you do a single change in the UI.  

    Do you want to say that the event is fired multiple times for the single property (the name is passed as a parameter)?

    Friday, June 20, 2014 11:29 AM
  • Yes, it fired multiple times for RequiredAttendees/optionalattendees and resource Property.

    Friday, June 20, 2014 5:04 PM
  • It looks like you are trying to set the RequiredAttendees/optionalattendees properties in the Write event handling routine. Is this the case?

    Do you develop a VSTO based add-in?

    If so, use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. Set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. See Systematically Releasing Objects for more information.

    Friday, June 20, 2014 6:03 PM
  • Hi Eugene,

    Thanks for your reply!

    The scenario i am talking about happens when i try to add attendee, there is no write event happened yet.

    I add attendee and property change event fires and i am also releasing com object on time. i have shared my code , let me know if you find anything wrong in it.

    Yes, i develop a VSTO based add-in



    Monday, June 23, 2014 9:20 AM
  • Hi Guys,

    is there anyone who is able to replicate this or let me know if something is wrong in my code.


    Tuesday, July 8, 2014 8:07 AM
  • Nitin,

    The body of the SetPageProperty function is missed.

    Tuesday, July 8, 2014 9:44 AM
  • Are you able to reproduce the issue with a single line of code where you add an attendee? Does the PropertyChange event fires multiple times in that case?
    Tuesday, July 8, 2014 9:45 AM
  • Hi Eugene,

    i commented out evrey bit of code in that case.

    Case "OptionalAttendees", "RequiredAttendees"
    'Dim AttendeeList As String = GetRecipients()
    'If Attendees <> AttendeeList Then
    'SetPageProperty(Browser, "attendees", AttendeeList)
    'Attendees = AttendeeList
    'End If

    but its still firing many times.

    here is my SetPageProperty code.

    Private Sub SetPageProperty(ByVal Browser As System.Windows.Forms.WebBrowser, ByVal PropertyName As String, ByVal PropertyValue As String)
    Log("SetPageProperty: " & PropertyName & "=" & PropertyValue)
    Dim script As String = "if(typeof outlook != ""undefined"") {outlook.setProperty(""" & PropertyName & """,""" & PropertyValue & """)}"
    Browser.Document.Window.DomWindow.execscript(script, "JavaScript")
    Catch ex As System.Exception
    Log("SetPageProperty:" & ex.Message)
    End Try
    End Sub


    Thursday, July 10, 2014 9:16 AM
  • Do you use Outlook in the script?

    Are you able to reproduce the issue with a newly created empty add-in project?

    Thursday, July 10, 2014 12:14 PM
  • This is normal and is also a 'most asked question'. If you search on "outlook propertychange fires multiple times" you get quite a few hits.

    The short answer is you're not doing anything wrong and what you see is expected.

    See this thread for a typical answer:

    Ken Slovak MVP - Outlook

    • Marked as answer by Nitrup Friday, July 11, 2014 9:18 AM
    Thursday, July 10, 2014 6:47 PM
  • Thanks for your reply Ken. At lesat, now i am on same page where others are.

    I am marking your reply as an answer. But, Is anything being done or will be done by Microsoft to handle this?



    Friday, July 11, 2014 9:18 AM
  • I expect nothing to change with this. It's been the same since I started programming Outlook in 1997 and hasn't changed since. I'd classify this as "by design".

    Ken Slovak MVP - Outlook

    Friday, July 11, 2014 1:48 PM