How to: Start content sharing conversations

[This is preliminary documentation and is subject to change.]

Describes how to start a Microsoft Lync 2013 Preview conversation that hosts content sharing by using the Microsoft Lync 2013 Preview API.

This topic describes how to start a new conversation, create a virtual whiteboard, upload a whiteboard to a conversation content bin, and then share the whiteboard in a conversation. The sample application shown in Figure 1 is a Windows Forms application that implements the Lync 2013 Preview API to let a user manage whiteboard collaboration in a conversation.

Important note Important

Whiteboard collaboration management is not supported in Lync UI suppression mode.

This topic discusses the following concepts in whiteboard sharing.

Figure 1 shows a sample conversation console application that lets a user manage virtual whiteboards on the sharing stage of a Microsoft Lync 2013 Preview conversation window.

Figure 1. Conversation whiteboard collaboration console.

Conversation whiteboard collaboration console

When a user selects the Project Plan whiteboard from the console shown in Figure 1, the whiteboard is displayed in a Lync 2013 Preview conversation window sharing stage as shown in Figure 2.

Figure 2. Whiteboard sharing in Lync 2013 conversation window.

Whiteboard sharing in Lync conversation window

Before the logic from this topic runs in your application, the Lync 2013 Preview client must be running. Your application must hold a reference to the Microsoft.Lync.Model.LyncClient object in a class field and have an event callback registered on the Client.StateChanged event.

Namespace declarations example

Add the following namespace declarations to your application

using Microsoft.Lync.Model;
using Microsoft.Lync.Model.Group;
using Microsoft.Lync.Model.Conversation;
using Microsoft.Lync.Model.Conversation.Sharing;
using System.Collections.Generic;


Field declarations example

Add the following class field declarations to your application.

        /// <summary>
        /// Lync client platform. The entry point to the API
        /// </summary>
        LyncClient _LyncClient;

        /// <summary>
        /// Represents a Lync conversation
        /// </summary>
        Conversation _conversation;

Form Load event example

The following example signs the user in to Lync 2013 Preview and registers event callback methods for the client and conversation manager events handled by the sample. The ConversationManager.ConversationAdded event is raised when the state of the ConversationManager.Conversations property changes as a new conversation is started. For information about how to sign into Lync 2013 Preview, see How to: Sign In to Lync.

This code is added to the Load event handler for your form.

            try
            {
                //Get the API entry point
                _LyncClient = LyncClient.GetClient();

                //Content sharing is not supported in UI suppression mode. Sample closes if Lync UI is suppressed
                if (_LyncClient.InSuppressedMode == true)
                {
                    MessageBox.Show("Lync Client is in UI Suppressed mode. Sharing is not supported.", "Application Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                    this.Close();
                }

                //Register for the three Lync client events needed so that application is notified when:
                // * Lync client signs in or out
                // * A new conversation is added (remotely via invite or locally by user)
                // * A conversation is removed (conversation ends)
                _LyncClient.StateChanged += _LyncClient_StateChanged;
                _LyncClient.ConversationManager.ConversationAdded += ConversationManager_ConversationAdded;
                _LyncClient.ConversationManager.ConversationRemoved += ConversationManager_ConversationRemoved;

                //If the Lync client is signed out, sign into the Lync client
                if (_LyncClient.State == ClientState.SignedOut)
                {
                    _LyncClient.EndSignIn(_LyncClient.BeginSignIn(
                        "terrya@contoso.com",
                        "terrya@contoso.com",
                        "MyPassword",
                        null,
                        null));
                }
            }
            catch (NotInitializedException)
            {
                MessageBox.Show("Client is not initialized.  Closing form", "Lync Client Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                this.Close();
            }
            catch (ClientNotFoundException)
            {
                MessageBox.Show("Client is not running.  Closing form", "Lync Client Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                this.Close();
            }

Before starting a conversation, make sure that you register an event handler for the ConversationManager.ConversationAdded event. To start a conversation, do the tasks in the following procedure:

Start a conversation

  1. Create a new conversation by calling the ConversationManager.AddConversation method.

  2. Register for events on the new conversation and add a user.

  3. Invite the new user to join the conversation

For information about starting a new IM conversation, see How to: Start an IM Conversation.

Add conversation example

The following example creates a conversation. The conversation is not started until a remote participant is added and initial IM text is sent. When the state of the ConversationManager.Conversations property changes with the addition of the new conversation, the ConversationManager.ConversationAdded event is raised.

Add this code to the Click event handler of a button on your form.

    _conversation = _LyncClient.ConversationManager.AddConversation();

Conversation event registration example

The following example registers for events on the new conversation and content sharing modality and then adds a participant. After the new participant is added, the Conversation.ParticipantAdded event callback is invoked.

Important note Important

Adding a participant to a conversation is creating a reference to a locally cached Microsoft.Lync.Model.Conversation.Participant object and then adding the reference to the Conversation.Participants property of the conversation.

To create an invitation which Microsoft Lync Server 2013 Preview sends to the user being invited to the conversation, send an IM message from the Microsoft.Lync.Model.Conversation.InstantMessageModality object in the conversation. Sending the initial IM text also starts the conversation.

Add the following code to the ConversationAdded event callback method.

if (_conversation == e.Conversation)
{
    ((Modality)_conversation.Modalities[ModalityTypes.ContentSharing]).ModalityStateChanged += Modality_ModalityStateChanged;
    ((Modality)_conversation.Modalities[ModalityTypes.ContentSharing]).ActionAvailabilityChanged += _sharingModality_ActionAvailabilityChanged;
    ((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).ContentAdded += _sharingModality_ContentAdded;
    ((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).ContentRemoved += _sharingModality_ContentRemoved;

    //Register for conversation state changes such as Inactive->Active or Active->Terminated.
    _conversation.StateChanged += _conversation_StateChanged;

    //Register for participant added events on the new conversation
    //The next important action in the chain of conversation intiating action happens in the ParticipantAdded event handler.
    _conversation.ParticipantAdded += _conversation_ParticipantAdded;
    _conversation.ParticipantRemoved += _conversation_ParticipantRemoved;
 
    //Add a person to the conversation. IMPORTANT: The local user is automatically added so your code does not
    //add the local user.
    Participant newParticipant = _conversation.AddParticipant("hollyh@contoso.com");
}

Participant event registration example

The following example registers for the new participant’s ActionAvailabilityChanged event and sends the first IM text if the new participant is not the local participant. The initial IM text forms the text of the invitation that the new user sees.

Important note Important

By registering for the ActionAvailabilityChanged event on the added participant’s content sharing modality, your application is notified if the local user is invited to share content presented by another participant.

If another participant invites the local participant to share content, the .Call the Modality.Accept method on that participant’s content sharing modality. If the invitation is accepted then the conversation content sharing modality is automatically connected by the platform.

Add this code to your callback on the Conversation.ParticipantAdded event.

((Modality)e.Participant.Modalities[ModalityTypes.ContentSharing]).ActionAvailabilityChanged += _ParticipantsharingModality_ActionAvailabilityChanged;
if (!e.Participant.IsSelf)
{
    ((InstantMessageModality)_conversation.Modalities[ModalityTypes.InstantMessage]).BeginSendMessage("Hello. I would like to share something with you.", (ar) => {
        ((InstantMessageModality)_conversation.Modalities[ModalityTypes.InstantMessage]).EndSendMessage(ar);
    }
    , null);
}


Important note Important

Do not register the same event callback method for both the conversation and participant’s Modality.ActionAvailabilityChanged event.

Connect the Microsoft.Lync.Model.Conversation.Sharing.ContentSharingModality object in the conversation modalities collection before uploading a whiteboard to a conversation and then sharing it. You can connect the ContentSharingModality at any time after the conversation state is ConversationState.Active.

After you call the Modality.BeginConnect Method, the state of the modality changes from ModalityState.Disconnected to ModalityState.Connecting and then to ModalityState.Connected.

Content sharing modality connect example

The following example verifies that the content sharing modality state allows the connect action and then calls the Modality.BeginConnect method. A lambda expression is used instead of a callback method in this example.

Add the following code to the Conversation.StateChanged event callback method.

If (e.NewState == ConversationState.Active)
{
    if (((Modality)_conversation.Modalities[ModalityTypes.ContentSharing]).CanInvoke(ModalityAction.Connect))
    {
        ((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing])
            .BeginConnect((ar) => {
               ((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).EndConnect(ar);
            }
            , null);
    }
}

Handle the content modality ActionAvailabilityChanged event example.

The following example enables or disables the content-sharing action UI buttons on the sample form according to the current availability of a content sharing modality action.

The sample application declares a UI button for each content-sharing modality action. By default these buttons are disabled. When a modality action is available, the corresponding command button is enabled. These action state changes are reflected in the Modality.ActionAvailabilityChanged event that is raised on the platform thread. In order to update the property of a control on the UI thread, code on the platform thread must create an instance of a delegate method and then invoke that delegate on the UI thread.

        /// <summary>
        /// Raised when the availability of an action on the content sharing modality changes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _sharingModality_ActionAvailabilityChanged(object sender, ModalityActionAvailabilityChangedEventArgs e)
        {
            EnableDisableButtonDelegate d = new EnableDisableButtonDelegate(EnableDisableButton);
            switch (e.Action)
            {
                case ModalityAction.CreateShareableWhiteboardContent:
                    this.Invoke(d, new object[] { ShareWhiteboard_Button, e.IsAvailable });
                    break;
            }
        }


The following example enables the local user to accept or reject a remote user’s invitation to share a whiteboard. The example enables two buttons on the UI that give the user the option to accept or decline the invitation.

        /// <summary>
        /// Raised when the availability of an action on the content sharing modality changes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _ParticipantsharingModality_ActionAvailabilityChanged(object sender, ModalityActionAvailabilityChangedEventArgs e)
        {
            EnableDisableButtonDelegate d = new EnableDisableButtonDelegate(EnableDisableButton);
            switch (e.Action)
            {
                case ModalityAction.Accept:
                    _RemoteParticipantSharingModality = (ContentSharingModality)sender;
                    this.Invoke(d, new object[] { Accept_Button, e.IsAvailable });
                    break;
                case ModalityAction.Reject:
                    _RemoteParticipantSharingModality = (ContentSharingModality)sender;
                    this.Invoke(d, new object[] {Reject_Button, e.IsAvailable });
                    break;
            }
        }

The following example enables or disables a modality command button on the sample UI according to the availability of the action.

        private delegate void EnableDisableButtonDelegate(Button buttonToUpdate, Boolean newButtonEnableState);

        /// <summary>
        /// Enables or disables a UI button based on the actionAvailability
        /// </summary>
        /// <param name="buttonToUpdate"></param>
        /// <param name="newButtonEnableState"></param>
        private void EnableDisableButton(Button buttonToUpdate, Boolean newButtonEnableState)
        {
            buttonToUpdate.Enabled = newButtonEnableState;
        }


When all these tasks are completed, the state of Lync 2013 Preview API objects are as described in the following table.

Lync 2013 Preview API conversation objects

Object

Description

State

Microsoft.Lync.Model.LyncClient

Client platform API entry point.

ClientState.SignedIn

Microsoft.Lync.Model.Conversation.Conversation

The content sharing conversation.

ConversationState.Active

Microsoft.Lync.Model.Conversation.Sharing.ContentSharingModality

The conversation content sharing modality.

NoteNote
Each participant in the active conversation exposes a collection of modalities that include a content sharing modality. Each of these content sharing modality objects is also connected.

ModalityState.Connected

Community Additions

Show:
© 2014 Microsoft