Walkthrough: Fill a Contact List (Lync 2010 SDK)

This topic demonstrates how to iterate through the contacts for a client. This process can be useful to fill a collection of contact names for use in your user interface. A custom group and a distribution group are collections of contacts. By iterating on the contact collection within a group, you obtain the individual contacts that comprise the group.

To fill a contact list, you obtain instances of the following classes:

You call the following methods:

You register for the following events:

Filling a Contact List from a Custom Group

The classes, methods, and events appearing in the following illustration are used in the process of filling a contact list from a custom group.

Hh345241.OCOM_WalkthroughContactList(en-us,office.14).jpg

To fill a contact list from a custom group, you start by getting a collection of Group class instances from the ContactManager class. This collection is available using the Groups property of the contacts and groups manager. The collection contains both custom groups defined by a local user and other groups provided by Microsoft Lync Server 2010.

  1. Get the LyncClient instance.

    Verify that the client is signed in to Lync 2010. For information about signing in to Lync 2010, see Walkthrough: Sign In to Lync (Lync 2010 SDK).

  2. Create a ContactSubscription instance by calling into CreateSubscription.

    The ContactSubscription instance exposes an empty Contacts collection that you fill in a following step.

  3. Iterate through the Groups collection of the ContactManager instance to find the groups that contain the contacts that you want to list.

  4. Register for group events on each group.

    For more information about handling group events, see Handle Events for a Group (Lync 2010 SDK)

  5. Iterate through the contact collection of the group using a foreach loop.

  6. Register for contact events on each contact.

    For more information about handling Contact events, see Handle Events for a Contact (Lync 2010 SDK).

  7. Add the Contact instance to the subscription if a contact is not already in the ContactSubscription instance you created in step 2.

  8. Get presence item values of interest from each contact.

    For information about getting presence items, see Walkthrough: Get Current Contact Availability (Lync 2010 SDK).

    Tip

    A contact’s properties and presence information may not be complete at the time you obtain the Contact instance and query for presence or read properties. For this reason, it is important that you handle the contact events you register for in the previous step. Contact events are raised as each additional element of presence information is sent to your client.

  9. Insert code to take the action you want for each contact.

    The next example adds the contact to an instance of the ContactSubscription class and to a list used by the user interface.

  10. Call Subscribe on your ContactSubscription instance after you have completed the foreach loop on the contact collection.

    The Subscribe method creates a request on Lync Server 2010 that asks for continuous updates of the presence information from each contact added to the subscription.

Filling a Contact List from a Distribution Group

A distribution group is also a collection of contacts.

  1. Get the LyncClient instance. Verify that the client is signed in to the server. For information about signing in to Lync Server 2010, see Walkthrough: Sign In to Lync (Lync 2010 SDK).

  2. Select a distribution group. For more information about searching for distribution groups, see Walkthrough: Search For a Contact (Lync 2010 SDK).

  3. Call the BeginGetAllMembers method on the distribution group instance, passing the callback delegate as a parameter. This starts an operation that returns a ContactCollection instance when you call EndGetAllMembers

  4. Create the callback method to manipulate the instance of the ContactCollection class returned in the callback.

Examples

The following examples execute the basic logic necessary to obtain Contact instances that can be used to build a list of contacts in a user interface. The first example iterates on all groups returned by the Groups property and gets the contacts from all groups of the GroupType.CustomGroup type.

Fill a contact list from a custom group

This example illustrates steps 3 and following from the procedural steps to fill a contact list from a custom group. The example method, GetGroupContacts is called for each custom group whose contacts are to be listed. The example iterates on the contact collection of a custom group. The example defines a list of contact information types as a collection with a call into the GetContactInformation method. Individual presence items are obtained with a call into GetContactInformation. The example uses this latter method to get both the display name of a contact and the current availability of the contact. For more information about getting contact information, see Walkthrough: Display a Contact Card (Lync 2010 SDK)

        
        private ContactSubscription newSubscription = _ContactManager.CreateSubscription();
        private Dictionary<ContactInformationType, object> _ContactInformation = new Dictionary<ContactInformationType, object>();


        foreach (Group _Group in _ContactManager.Groups)
        { 
            if (_Group.Type == GroupType.CustomGroup)
            {
                GetGroupContacts(_Group);
            }
        }

        /// Iterate on a group contact collection and update UI with contact.
        /// Triggered by a state change event on a group.
        /// <param name="group">Group. Group to iterate</param>
        /// <param name="newSubscription">ContactSubscription. Contact subscription to add contacts to</param>
        private void GetGroupContacts(Group group,)
        {
            group.ContactAdded += _GroupContactAdded;
            group.ContactRemoved += _GroupContactRemoved;

            // Iterate on the contacts in the group.
            foreach (Contact _Contact in group)
            { 
                // Test if contact already exists in subscription.
                if (newSubscription.Contacts.Contains(_Contact) == false)
               {
                    // Add contact to contact subscription.
                    newSubscription.AddContact(_Contact);

                    // Register for contact event changes.
                    _Contact.SettingChanged += new EventHandler<ContactSettingChangedEventArgs>(_ContactSettingChanged);
                    _Contact.ContactInformationChanged += new EventHandler<ContactInformationChangedEventArgs>(_Contact_OnInformationChanged);

                    
                   // Get contact information from the contact.
                   // For more information, see the walkthroughs on displaying a contact card and querying contact availability.

                   // Trigger update of the user interface to reflect the contact list change.
               }
           }
           //Specify contact presence items to subscribe for
           ContactInformationType[] ContactInformationTypes = { ContactInformationType.Availability, ContactInformationType.ActivityId };


           //Initiate batch one subscription for all contacts found in groups of specified type.
           newSubscription.Subscribe(ContactSubscriptionRefreshRate.Low, ContactInformationTypes);
       } 

Event Handlers

This event handler registers for contact events on any Contact added to the group after verifying that the contact is not in the contact subscription.

       void _GroupContactAddedEvent(Object source, GroupMemberChangedEventArgs data)
       {
            if (newSubscription.Contacts.Contains(data.Contact) == false)
            {
                // Register for contact event changes.
                data.Contact.SettingChanged += _ContactSettingChanged;
                data.Contact.ContactInformationChanged += _Contact_OnInformationChanged;

                // Add contact to contact subscription.
                newSubscription.AddContact(data.Contact);
                newSubscription.Subscribe(ContactSubscriptionRefreshRate.Low, ContactInformationTypes);
            }
       }

This event handler unregisters for events on the contact that was removed from the group, removes the contact from the subscription, and then renews the subscription to all contacts.

Important

A single Contact instance can be in multiple groups. You should verify that the contact removed from the given group is not in other custom contact groups. If you unsubscribe a Contact instance in this event handler without verifying that the contact is not in other custom groups, you will not receive further contact information updates for the contact.

        void _GroupContactRemovedEvent(Object source, GroupMemberChangedEventArgs data)
        {
            if (data.Contact.CustomGroups.Count == 0)
            {
                // UnRegister for contact event changes.
                data.Contact.SettingChanged -= _ContactSettingChanged;
                data.Contact.ContactInformationChanged -= _Contact_OnInformationChanged;
                // Remove contact to contact subscription.
                newSubscription.RemoveContact(data.Contact);
                // Update contact subscription with current contact list.
                newSubscription.Subscribe(ContactSubscriptionRefreshRate.Low, ContactInformationTypes);
            }
        }

Contact setting changed handler

Contact information changed handler

        /// <summary>
        /// Handles event raised when contactModel presence item collection has been updated.
        /// </summary>
        /// <param name="source">object. Contact whose information has been updated.</param>
        /// <param name="data">ContactInformationChangedEventArgs. The contact information that changed.</param>
        /// <remarks>This callback is used to update the public contactModel card string class property ContactCardInformation.
        /// The event data parameter exposes a member property, ChangedPresenceItems. This property is a list of ContactInformationType. The types in 
        /// the list are the presence item types whose change resulted in this state change event.
        /// </remarks>
        void _Contact_OnInformationChanged(Object source, ContactInformationChangedEventArgs data)
        {
            Contact _contact = (Contact)source;
            //The IDictionary returned from call into GetContactInformation contains the 
            //types and contact information value changes that triggered the event.
            IDictionary<ContactInformationType, object> pd = _contact.GetContactInformation(data.ChangedContactInformation);
        }

Fill a contact list from a distribution group

The following example is a method that gets all contacts contained in a distribution group.

/// Gets all contacts in a distribution group.
        /// Callback method is DistributionGroupCallback.
        /// <param name="selectedIndex">int: Index of selected distribution group in list of distribution groups</param>
        public void ExpandGroup(DistributionGroup groupToExpand, Subscription newSubscription)
        {
            groupToExpand.GetAllMembers(this.DistributionGroupCallback, newSubscription);
        }

The next example is the method created to react to the callback from the previous GetAllMembers method call. This example fills an ArrayList with the contacts contained in the instance of the ContactCollection class returned by the callback and raises an event which can be used to trigger a user interface update.

/// Callback for the GetAllMembers method of DistributionGroup.
        /// Fills an array of contacts for use by the user interface.
        /// Raises MembershipChangedEvent to trigger UI update.
        /// <param name="source">DistributionGroup: The distribution group containing the contacts</param>
        /// <param name="collection">ContactCollection: The collection of contacts in the distribution group</param>
        /// <param name="_asyncOperation">IASynchronousOperation</param>
        public void DistributionGroupCallback(DistributionGroup source, ContactCollection collection, IAsynchronousOperation _asyncOperation)
        {
            contactNameArray = new ArrayList();
            Subscription newSubscription = _asyncOperation.AsyncState as Subscription;
            foreach (Contact aContact in collection)
            {
                // Test if contact already exists in subscription.
                if (newSubscription.Contacts.Contains(aContact) == false)
               {
                    // Add contact to contact subscription.
                    newSubscription.AddContact(aContact);

                    // Register for contact event changes.
                    aContact.ContactPropertyChanged += c_ContactPropertyChanged;
                    aContact.PresenceItemsChanged += c_PresenceItemsChanged;
                    aContact.UriChanged += c_UriChanged;
                    
                   // Get presence items from the contact.
                   // For more information, see the walkthroughs on displaying a contact card and querying contact availability.

                   // Trigger update of the user interface to reflect the contact list change.
               }
            }
           //Specify contact presence items to subscribe for
           PresenceItemType[] presenceTypes = { PresenceItemType.Availability, PresenceItemType.ActivityId };

           //Initiate batch one subscription for all contacts found in groups of specified type.
           newSubscription.Subscribe(SubscriptionFreshness.Low, presenceTypes);
        }

See Also

Concepts

Writing Lync 2010 SDK Applications

Lync Model API Contacts and Groups Walkthroughs (Lync 2010 SDK)

Handle Events for a Contact (Lync 2010 SDK)

Walkthrough: Display a Contact Card (Lync 2010 SDK)