A Metro style interface to Lync – Part 5

This article was imported from codelync.com

Creating the Metro style app

In the previous post, we defined our WCF service interface and fleshed it out with the code necessary to interact with the Lync client.

Now it’s time to look at the Metro style application that will use the WCF service to display Lync contacts.

The developer preview of Visual Studio 11 includes a number of templates for building Metro style apps. Creating and running a new application using the “Grid Application” template gives us a skeleton application that looks like this:

Metro style template app

This will be the starting point for our Metro style Lync app.

The first thing to do is add a reference to the WCF service using the “Add Service Reference” Solution Explorer. I’m then able to create an instance of the proxy to the WCF service:

var _callbackHandler = new LyncMetroCallbackHandler();
_callbackHandler.ContactAvailabilityChanged += CallbackHandler_AvailabilityChanged;

_client = new LyncMetroClient(new InstanceContext(_callbackHandler));
await _client.OpenAsync();

var groups = await _client.GetContactsAsync();
var dataSource = new DataSource(groups);

Groups = source.GroupedCollections;

There are a few things to note here. First is the use of the new await keyword when calling OpenAsync and GetContactsAsync. This is new to .NET framework 4.5, and allows calling asynchronous methods with an inline syntax. This is a great productivity improvement, and explained in more detail by the one and only Anders Hejlsberg here. It’s also worth noting that the *Async methods were generated automatically in the WCF service proxy – the Open() and GetContacts() methods that would have been generated in a non-Metro style application don’t exist. With the aim of keeping the UI fast and fluid, you are forced to call any potentially long running calls asynchronously.

Line 6 creates a new DataSource object. The code generated by the Visual Studio template includes a data structure that contains sample data. DataSource is a slightly modified version, which gets populated from the LyncGroups collection that’s returned from the call to GetContactsAsync(). The data in DataSource then gets assigned to the Groups property in this class, which is bound to the UI, MVVM-style.

Line 1 instantiates a new object of type LyncMetroCallbackHandler. This implements the ILyncMetroCallback interface in our WCF service, and handles availability updates for contacts. The definition is as follows:

public class LyncMetroCallbackHandler : ILyncMetroCallback
{
    public event EventHandler<AvailabilityChangedEventArgs> ContactAvailabilityChanged = delegate { };

    public void AvailabilityChanged(string sipUri, Availability availability)
    {
        ContactAvailabilityChanged(this, new AvailabilityChangedEventArgs(sipUri, availability));
    }

    Task ILyncMetroCallback.AvailabilityChangedAsync(string sipUri, Availability availability)
    {
        var task = new Task(() => AvailabilityChanged(sipUri, presenceState));
        task.Start();
        return task;
    }
}

This class defines an event that gets raised when the WCF service calls into this with a presence change. New for Metro style apps is the Async method that returns a Task. This forces you to provide logic that runs asynchronously when handling callbacks from the WCF service, again keeping the UI fast and fluid.

The method that handles the LyncMetroCallbackHandler.ContactAvailabilityChanged event is as follows:

void CallbackHandler_AvailabilityChanged(object sender, AvailabilityChangedEventArgs e)
{
    Dispatcher.Invoke(CoreDispatcherPriority.Normal,UpdateContactAvailability, sender, e);
}

void UpdateContactAvailability(object sender, InvokedHandlerArgs e)
{
    var args = (AvailabilityChangedEventArgs)e.Context;

    foreach (DataCollection group in Groups)
    {
        foreach (DataItem contact in group)
        {
            if (contact.SipUri == args.SipUri)
                contact.Availability = args.Availability;
        }
    }
}

This logic updates the Availability property against any of our LyncContact objects that have a matching Sip Uri. Because the Availability property is a target for UI to bind to, we need to ensure that the property is updated on the UI thread, by calling Dispatcher.Invoke.

Finally, with a bit of Xaml tweaking, we have our Metro style Lync interface. Here are my Lync contacts:

Lync contacts

Scrolling across to see the contacts in my “Applications” group:

Contacts in the Application group

“TimePrompt Authoriser” contact coming online:

Timepromt Authoriser coming online

In “Snap” view:

Snap view

This is part 5 in a series of 5:

Paul Nearney Written by:

Paul is a software solution architect specialising in Microsoft Teams, and the founder of Chimu Software