Learn how to add or remove a custom group from a user’s contact list in Microsoft Lync 2013 by using Microsoft Lync 2013 SDK.
Applies to: Lync 2013 | Lync Server 2013
Watch the video: Add, rename, and delete custom groups in Lync
Custom group overview
When a local user performs any of the group operations described in this topic using Lync 2013, the result of the operation must be visible to the local user immediately on any signed-in endpoint. To make this possible, the API sends the group operation request to Microsoft Lync Server 2013 and result is sent to all of the user’s signed-in endpoints. For this reason, group operations are asynchronous even though only the local user sees the result of the operation. For information about asynchronous coding patterns with the Microsoft Lync 2013 API, see Asynchronous programming in Lync SDK.
Prerequisites
The prerequisites for adding or removing a custom group are as follows:
Microsoft Lync 2013 must be installed and running on the development computer.
You must have sign-in credentials for Microsoft Lync Server 2013.
Microsoft Lync 2013 SDK must be installed on the development computer.
Learn about the distribution a Microsoft Lync 2013 group and the classes and events in Microsoft Lync 2013 SDK that let you programmatically iterate on the contacts and any nested distribution groups.
Learn about the Microsoft Lync 2013 classes and enumerations that encapsulate all of the attributes of a Lync 2013 contact.
Contacts and groups are available when the user is signed in to Lync 2013. Read about How to: Sign a user in to Lync and be sure that your application logic provides this capability before adding a contact list to your UI.
Add a custom group
To add a new custom group, call the BeginAddGroup method on the contacts and groups manager, supplying the name of the new group. You must call EndAddGroup to complete the operation. You receive the GroupAdded event when the new custom group is added. Read the Group property to get an instance of the new custom group that is added.
To add a custom group
In your form class, create an event handler for the GroupAdded event.
Call BeginAddGroup on ContactManager, passing a string containing the requested group name. If you want to block execution on your UI thread until the operation completes, call EndAddGroup after the first call. To avoid blocking your UI thread, pass a System.AsyncCallback method into BeginAddGroup, and then call EndAddGroup within the callback when it's invoked from the Lync thread.
The following figure illustrates the classes, methods, and events used in the process of adding a custom group and adding a contact to the group.
Add a distribution group
A distribution group is created outside of the scope of this API. It's obtained and added to a user’s contact list using the Microsoft Lync 2013 API. For information about obtaining an existing distribution group, see How to: Search for a contact or distribution group in Lync SDK.
When you have obtained a distribution group in a set of search results, add the distribution group to the contact list by calling into BeginAddGroup, passing the distribution group as the first argument.
Remove a custom group
To remove a custom group, call the BeginRemoveGroup method on the contacts and groups manager, supplying the group to be removed. If the group is removed, you receive the GroupRemoved event on the ContactManager instance.
To remove a custom group
In your form class, create an event handler for the GroupRemoved event.
Catch the Group.NameChanged event raised when the state of the custom group has changed as a result of the operation.
Code examples: Add, remove, and rename custom groups
The following example declares a WPF window that contains a list box that shows all contact group names and a set of buttons that let a user add, remove, and rename custom groups.
XAML
<Windowx:Class="GroupManager.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="My Group Manager"Height="315"Width="439"Loaded="Window_Loaded_1"><Grid><Grid.RowDefinitions><RowDefinitionHeight="30*"/><RowDefinitionHeight="5*"/></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinitionWidth="80*"/><ColumnDefinitionWidth="30*"/></Grid.ColumnDefinitions><StackPanelGrid.Row="0"Grid.Column="0" ><ListBoxName="GroupList_ListBox"Width="200"Height="195"Margin="10,10,10,10"/></StackPanel><StackPanelGrid.Row="0"Grid.Column="1"><TextBoxHeight="23"Name="GroupName_textbox"TextWrapping="Wrap"Text=""Margin="10,10,10,10"/><ButtonContent="Add Group"Name="AddGroup_Button"Click="AddGroup_Button_Click_1"Margin="10,10,10,10"/><ButtonContent="Remove Group"Name="RemoveGroup_Button"Click="RemoveGroup_Button_Click_1"Margin="10,10,10,10"/><ButtonContent="Rename Group"Name="RenameGroup_Button"Click="RenameGroup_Button_Click_1"Margin="10,10,10,10"/></StackPanel></Grid></Window>
The following figure shows the example application UI with the three default groups for the signed-in user. No custom groups have been created for this user.
The following example handles group collection events on the ContactManager object, fills the group list in the UI, and handles click events for buttons in the UI.
C#
using System.Windows;
using Microsoft.Lync.Model;
using Microsoft.Lync.Model.Group;
using System.Diagnostics;
using System;
using System.Collections.Generic;
namespaceGroupManager
{
///<summary>/// Interaction logic for MainWindow.xaml///</summary>publicpartialclassMainWindow : Window
{
LyncClient _LyncClient;
private Dictionary<string, GroupWrapper> _Groups = new Dictionary<string, GroupWrapper>();
publicMainWindow()
{
InitializeComponent();
}
///<summary>/// Adds a new custom group to the signed in user's contact list///</summary>///<param name="sender"></param>///<param name="e"></param>privatevoidAddGroup_Button_Click_1(object sender, RoutedEventArgs e)
{
if (GroupName_textbox.Text.Length > 0)
{
_LyncClient.ContactManager.BeginAddGroup(
GroupName_textbox.Text,
(ar) =>
{
try
{
_LyncClient.ContactManager.EndAddGroup(ar);
}
catch (LyncClientException lce)
{
Debug.WriteLine(
"Lync client exception on add group: " +
lce.Message);
}
},
null);
GroupName_textbox.Text = string.Empty;
}
}
privatevoidRemoveGroup_Button_Click_1(object sender, RoutedEventArgs e)
{
if (GroupList_ListBox.SelectedItem == null)
{
return;
}
try
{
GroupWrapper groupToRemove;
if (_Groups.TryGetValue(GroupList_ListBox.SelectedItem.ToString(), out groupToRemove))
{
_LyncClient.ContactManager.BeginRemoveGroup(
groupToRemove.LyncGroup,
(ar) =>
{
try
{
_LyncClient.ContactManager.EndRemoveGroup(ar);
}
catch (LyncClientException lce)
{
Debug.WriteLine(
"Lync client exception on remove group: " + lce.Message);
}
},
null);
}
else
{
Debug.WriteLine(
GroupList_ListBox.SelectedItem.ToString() +
" was not found in the dictionary");
}
}
catch (InvalidOperationException)
{
Debug.WriteLine(
"Invalid operation in RemoveGroup_Button_Click1");
}
}
privatevoidRenameGroup_Button_Click_1(object sender, RoutedEventArgs e)
{
if (GroupList_ListBox.SelectedItem == null || GroupName_textbox.Text.Length < 1)
{
return;
}
GroupWrapper groupToRename;
if (_Groups.TryGetValue(GroupList_ListBox.SelectedItem.ToString(), out groupToRename))
{
//Rename a Group after casting to CustomGroup
((CustomGroup)groupToRename.LyncGroup).BeginRename(
GroupName_textbox.Text,
(ar) =>
{
try
{
((CustomGroup)groupToRename.LyncGroup).EndRename(ar);
}
catch (LyncClientException lce)
{
Debug.WriteLine(
"Lync client exception on rename group: " +
lce.Message);
};
},
null);
GroupName_textbox.Text = string.Empty;
}
else
{
Debug.WriteLine(
GroupList_ListBox.SelectedItem.ToString() +
" was not found in the dictionary");
}
}
privatevoidWindow_Loaded_1(object sender, RoutedEventArgs e)
{
//GroupList_ListBoxtry
{
_LyncClient = LyncClient.GetClient();
_LyncClient.ContactManager.GroupAdded += ContactManager_GroupAdded;
_LyncClient.ContactManager.GroupRemoved += ContactManager_GroupRemoved;
LoadList();
}
catch (LyncClientException lce)
{
Debug.WriteLine(
"Lync client exception on GetClient() in Window Loaded " +
lce.Message);
}
}
///<summary>/// Loads a list box with existing contact list groups/// by iterating on the Groups collection of the ContactManager /// property on LyncClient.///</summary>privatevoidLoadList()
{
GroupList_ListBox.Items.Clear();
foreach (Group groupin _LyncClient.ContactManager.Groups)
{
//The Group is wrapped in a custom class to allow//override of ToString() method
GroupWrapper gWrap = new GroupWrapper(group);
//GroupWrapper class registers for the Group.NameChanged//event and bubbles event to UI layer so the //listbox gets reloaded with new name
gWrap.NameChanged += gWrap_NameChanged;
GroupList_ListBox.Items.Add(gWrap);
if (_Groups.ContainsKey(group.Name))
{
continue;
}
//Dictionary of GroupWrapper objects with group name as key
_Groups.Add(group.Name, gWrap);
}
}
voidContactManager_GroupRemoved(object sender, GroupCollectionChangedEventArgs e)
{
this.Dispatcher.Invoke(new DelegatedMethod(RemoveGroupFromList), newobject[] {e.Group});
}
voidContactManager_GroupAdded(object sender, GroupCollectionChangedEventArgs e)
{
this.Dispatcher.Invoke(new DelegatedMethod(AddGroupToList), newobject[] { e.Group });
}
privatedelegatevoidDelegateNoParams();
privatedelegatevoidDelegatedMethod(Group group);
privatevoidRemoveGroupFromList(Group group)
{
GroupWrapper groupToRemove;
if (_Groups.TryGetValue(group.Name, out groupToRemove))
{
if (GroupList_ListBox.Items.Contains(groupToRemove))
{
GroupList_ListBox.Items.Remove(groupToRemove);
_Groups.Remove(group.Name);
}
else
{
Debug.WriteLine(group.Name + " was not found in list");
}
}
}
privatevoidAddGroupToList(Group group)
{
if (!GroupList_ListBox.Items.Contains(group.Name))
{
GroupWrapper gWrap = new GroupWrapper(group);
gWrap.NameChanged += gWrap_NameChanged;
GroupList_ListBox.Items.Add(gWrap);
_Groups.Add(gWrap.LyncGroup.Name, gWrap);
}
}
voidgWrap_NameChanged(string oldName, string newName)
{
this.Dispatcher.Invoke(new DelegateNoParams(LoadList));
}
}
internalclassGroupWrapper
{
publicdelegatevoidNameChangedDelegate(string oldName, string newName);
publicevent NameChangedDelegate NameChanged;
Group _group;
privatestring originalName;
publicoverridestringToString()
{
return _group.Name;
}
public Group LyncGroup
{
get
{
return _group;
}
}
internalGroupWrapper(Group group)
{
_group = group;
originalName = group.Name;
_group.NameChanged += _group_NameChanged;
}
void _group_NameChanged(object sender, GroupNameChangedEventArgs e)
{
if (NameChanged != null)
{
NameChanged(originalName, e.NewName);
originalName = e.NewName;
}
}
}
}
This module provides instruction on how to create groups for distributing email to multiple users within Exchange Online. It also explains how to create groups to support collaboration in SharePoint Online.