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:
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:
Scrolling across to see the contacts in my “Applications” group:
“TimePrompt Authoriser” contact coming online:
In “Snap” view:
This is part 5 in a series of 5:
- Part 1 – Testing Lync on the Developer Preview tablet
- Part 2 – Testing a custom Lync application on the Developer Preview tablet
- Part 3 – Calling the Lync API from a Metro style app
- Part 4 – Creating the WCF Service
- Part 5 – Creating the Metro style app