This blog attempts to be a collection of how-to examples in the Microsoft software stack - things that may take forever to find out, especially for the beginner. I see it as my way to return something to the Microsoft community in exchange for what I learned from it.

27 October 2013

Why?Early this year I blogged about TtcSocketHelper, an MVVM friendly helper object that allowed you connect two Windows Phone 8 devices to each other using a socket.I made two games with it– Pull the Rope and 2 Phone Pong, head-to-head style games that are played over two phones, exchanging JSON data to keep things in sync. A lot of things happened the last 10 months: super cheap devices entered the market – most notably the Nokia Lumia 520. It is a full fledged Windows Phone 8, but it’s super cheap and as a consequence it does not support NFC (and thus no tap+send). That apparently is of no concern to buyers, as according to AdDuplex stats, it took off like a bat out of hell. In just six months it grabbed what is now almost 33% of the Windows Phone 8 market. In other words, by limiting my app to NFC enabled phones I cut myself off from a significant – and growing – part of the market.

PhonePairConnectionHelper – supporting Bluetooth browsingSo I rewrote TtcSocketHelper into PhonePairConnectionHelper – basically the same class, but it now supports connecting phones using tap+send as well as by using the tried and tested way of Bluetooth pairing. Since October 21st 2 Phone Pong 1.3.0 is in the store, proudly powered by this component, now enabling my game to be played by 50% more people!In this article I am going to concentrate on connecting via Bluetooth, as connecting via tap+send is already described in my article from January 2013.The start of the object is simple enough again, and actually looks a lot like the previous incarnation:

The most notable is now that the setup is being done in the constructor. The class still listens to the NavigationMessage and if so, it still calls the start method (this is for the tap+send route, that still works). The PeerFinder is set up to listen to TriggeredConnecState events (i.e. events that happen after a tap+send) but also - and this is important – to plain ole Bluetooth requests (ConnectionRequested event). The start method now, is pretty much changed:

The ConnectMethod enumeration, as you can already see from the code, enables you to indicate which method you want to use:

namespace Wp7nl.Devices
{
public enum ConnectMethod
{
Tap,
Browse
}
}

The Start method has an optional parameter that gives you the ability to choose a connection method, and if necessary add a display name. The display name only applicable for the Bluetooth method. The interesting thing is – if you don’t provide a name, like I did in the sample, it will just use the phone’s name as you have provided it (by giving it a name via Explorer if you connect if via a USB cable to your computer) - abbreviated to 15 characters. Why this is only 15 characters – your guess is as good as mine. If you call this method without any parameters, it uses default values and will try to connect using tap+send, just like before. Before selecting a method, you might want to check what connection methods the device support by using the two helper properties in the object:

Mind you – the helper is not so intelligent that it refuses to connect in a non-supported mode. And I don’t check for it in the sample app either. That is up to your app. But anyway – back up a little. If you try to connect via Bluetooth, the component tries to find all peers – that is, other phones running the same app, using FindAllPeersAsync, and fires the PeersFound event when it is done:

Your app has to subscribe to this event, and it then gets a list of “PeerInformation” objects. And PeerEvent has a number of properties, but the only one you will need to concern yourself is the “DisplayName” property. You display that in a list, a dropdown or whatever in your app, and after the user has made a selection, you call the Connect method:

And boom. You have a connection to the phone you have selected. The only thing that’s now missing is that the phone you have connected to, does not have a connection to you yet. But as you made the connection, the PeerFinder fired the ConnectionRequested event. Remember we set up a listener “PeerFinderConnectionRequested” to that in the constructor? Well guess what, part of the payload of the arguments of that event method gets is a PeerInformation object as well, containing the information to connect back to the phone that just connected to you :-). Which makes connecting back pretty easy:

And done. We know have a two-way socket connection using Bluetooth and we can call the SendMessage method just like before, and listen to result by subscribing to MessageReceived event. The only thing I did break in this helpers’ interface with regard to it predecessor is the ConnectionStatusChanged event type. This used to be

So if you subscribe to this event, you don’t have to check for args.State, but just for args itself. This was necessary to be able to fire connect events from DoConnect.The rest of the class is nearly identical to the old TtcSocketHelper, and I won’t repeat myself here.

To use this class

First, decide if you are going to for for the tap+send route or the Bluetooth route. My apps check the SupportsTap and SupportsBrowse properties. If NFC (thus tap+send) is supported, I offer both options and give the users a choice to select a connect method. If is not supported, I offer only Bluetooth.For the NFC route, the way to go still is:

A property to determine whether you are using Bluetooth or not (not = tap+send)

A property holding the selected Peer

A list of available peers

The callback for the helper’s PeersFound event. Not that everything here happens within a Dispatcher. As the PeersFound event comes back from a background thread, it has no access to the UI – but since it updates several bound properties, it needs that access – hence the Dispatcher.

and a command to allow the user to select a certain peer. Notice the Peers.Clear after the Peer is selected. That is because I use my HideWhenCollectionEmptyBehavior to display the UI for showing and selecting peers. This behavior is in the sample solution as code as I kind of forgot to add this to the last edition of my wp7nl library on codeplex.*ahem*

Two minor additions to the rest of the viewmodel: in the Init method, where I set up all the connectHelper, it now says:

Also not very complicated – a listpicker displays the peers and selects a peer, and the button fires the command to do the actual connecting. I rather like the use of HideWhenCollectionEmptyBehavior here – this automatically shows this piece of UI as there are peers in the list, and hides it when they are not. It’s rather elegant, if I may say so myself. On the picture right you can see it shows the name of my 920 – abbreviated to 15 characters.After the connection has been made – either by Bluetooth or by tap+send – you can use this app to chat just like the previous version.

Important things to know

If you are a developer who wants protect your customers from disappointments, you have checked the “NFC” as requirement in the WMAppManifest.xml when you built an app on top of my previous TtcSocketHelper. Remove that checkmark now. Or else your app still won’t be available for phones like the 520 that don’t have NFC. And that quite defies the point of this whole new class.

I have found out Bluetooth browsing on Windows Phone 8 has some peculiar things to take into account

You still have to be quite close together – somewhere within the meter range – to find peers. Once the connection is made, you can move further apart

The first phone to start searching for a peer, usually finds nothing. The second one finds one opponent, the third one two. The search process usually doesn’t last very long – in most cases just a few seconds – before the PeerFinder either gives up or comes back with a peer. It’s advisable not to call Connect automatically if you find only one peer – that might not be the one the user was looking for. Always keep the user in control.

If you connect via tap+send, you will only need to start the app on one of the phones and press the connect button – the other phone will automatically fire up the app (or even download it if it is not there) when the devices are tapped together.

For the Bluetooth route, the app needs to be started on both phones and on both phones you will need to press the connect button.

ConclusionThe app market is always in flux, that’s true for all platforms but that sure goes for Windows Phone. It’s important to stay in touch with those developments. There’s a lot of growth in the Windows Phone market – especially on the low end of the phones. Walking the extra mile for those groups is important – cater for as much users as you can. I hope I helped you a little with that, both by general example and actual code. Demo solution, as always, can be downloaded here.

17 October 2013

Updated November 11, 2013It was at my very first MVP Summit in February 2012 that I learned that Windows 8 XAML was not to have any behaviors. I remember distinctly being very angry first, telling the presenter I would be “dead in the water”, then upon reflection, calming down, and deciding to find out if I could plug the hole myself. And so I did, with the help of (in order of appearance) Geert van Horrik, Filip Skakun, and András Velvárt.

WinRtBehaviors saw the light in Spring 2012, shortly after said Summit. With 4,634 downloads, it being used in well-known top apps like Shazam, and being specifically mentioned at the 2013 edition of TechDays in both Belgium and The Netherlands (much to the surprise of colleagues and friends visiting there, not to mention myself) – I think I quite made my mark in the Windows XAML stack.

I also learned the downsides of having such a successful library, i.e. a lot of support requests. But today Visual Studio 2013 was released, and along with it the final version of the Behaviors SDK, so I released a version of Win8nl – the library with ported Windows Phone code that I built on top of WinRtBehaviors – and I made a yet-to-release version of Catch’em Birds for Windows on it, that totally works (since very recently) on that new version of Win8nl. So the days of the old WinRtBehaviors warhorse are over.

Win8nl 1.0.9 still supports Windows 8.0 and still downloads WinRtBehaviors, but if you target your app for Windows 8.1 you will see that there’s not longer a reference made to it when you download the Nuget Package.

Part of the library are the classes Behavior and Behavior<T>. These have the following implementations:

Based upon this class, you can port your existing behaviors from WinRtBehaviors (or from any other XAML framework, for what matters, virtually without any code change. I wrote this code in the early days of August 2013, but kind of sat on it as I wanted it to be part of the new Win8nl library. I sat a bit on it too long, as Fons Sonnemans published a very similar solution in September, so I can’t really claim prior art, but let just say it’s a logical thing to do and great minds apparently think alike. I took the EditorBrowsable thing from him, never thought of that.

What you will also notice is that the ‘hero’ behaviors EventToCommandBehavior and EventToBoundCommandBehavior, although still present, are now marked as Obsolete.This is for a very simple reason: the framework now has a standard way of doing such things. Would you use something like this in Windows 8.0 XAML:

Update November 11, 2013InvokeCommandAction has a CommandParameter too that you can bind to and refer to in the usual way. An interesting and useful feature of InvokeCommandAction was pointed out to me by fellow MVP Morten Nielsen – if don’t specify a CommandParameter, it defaults to passing the event arguments of the trapped event to the command. So if you have for instance this

And thus you can do something with the event arguments. So with InvokeCommandAction you can do everything you wanted to do with EventToBoundCommandBehavior. (Update ends)I would urge you to the utmost to no longer using EventToCommandBehavior and/or EventToBoundCommandBehavior from this day forward. Any support requests will simply be directed to this blog post ;).

Something I have been sitting on for very long – part of Catch’em Birds for Windows was a DataStateBehavior, which I basically cobbled together by reflecting into a Windows Phone 7 assembly, butchering stuff I didn’t need, understand or that did not compile, and finally arriving at something that kind of worked. For my goals. For obvious reasons I could not publish what was basically stolen and butchered Microsoft code and I am therefore very happy the Behavior SDK now has something to do the trick. If you now use DataStateBehavior in for instance a Windows Phone project like this:

Thus ends the story of WinRtBehaviors on October 17, 2013. I hope you have enjoyed it, and I also hope to have given you a clear migration path.

I wish the development team lots of luck with the support requests from especially my Belgian friends, who were quite ingenious in finding scenarios in which the EventToCommand behaviors did not work properly. The best one was something like “the behavior does not work if it’s in a data template from a resource file located in another assembly”. ;)

Feedback, comments and tokens of appreciation

If you spot things that are incorrect, or if you don't understand what I mean, please drop a comment on the offending article and I will help you ASAP. You can e-mail me at joostvanschaik at outlook dot com or contact me via twitter.

If you find the information on this blog useful (and apparently some 600+ people per day do on average) please let me know as well, that encourages me to keep doing this. Or do tell others - that made me an MVP; who knows what more it might bring ;-P

Disclaimer and legal stuff

Although I take great care in providing quality samples, all postings, articles and/or files on this site are provided "AS IS" with no warranties, and confer no rights. The views expressed on this blog are strictly my own and do not necessarily reflect the views of my employer, or anyone else on the planet for that matter.

I usually make original content, sometimes building upon other people's work. Sometimes I explain things that can be found elsewhere because I felt what I read was not clear enough for my limited mind so I explain it the way it finally clicked with me. In all cases I take great pains to be sure to link to people or articles who deserve the credit. If you think I have shortchanged you on the credits please let me know.

Please note, I do not work for Microsoft and while I proudly wear the title of "Microsoft Most Valueable Professional", my opinions, files offered, etc. do not represent, are approved of, endorsed by or paid for by Microsoft. The only power behind it is me and my sometimes runaway passion for parts of Microsoft's technology.