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.

29 January 2012

Preface
The checkbox has been been around in the Graphical User Interface for as long as I can remember doing GUI – since the early 90’s I guess. You know what, let’s make that “it’s been around for longer than I care to remember” ;). For my newest Windows Phone project I wanted something different. In stead of boring old

I wanted something like this:
Turns out you can do this in pure XAML. And almost entirely in Expression Blend, too. I could just post the XAML and be done with it, but I like to document the track I took, not only to educate you, but also to remember myself how the hell I got here in the first place ;-). Setting the stage

Double check the image’s properties, they should be as showed to the right.

Save the project

Creating style and control template

Open the project in Expression blend

Put one (or more, for all I care) CheckBoxes on the phone page.

Select one of them, then click in the main Blend menu “Object/Edit Style/Create Empty”.

In the dialog that follows, enter “Thumbupdowncheckboxstyle” for a name and select “Application” under “Define in”

You will get a screen with a single CheckBox. Right click it, select “Edit template/Create Empty”.

In the dialog that follows, enter “Thumbupdowncheckboxtemplate” for a name and select “Application” under “Define in”

First thing you will notice is that the selected CheckBox completely disappears from your design surface. That’s because basically you have replaced the entire look for the CheckBox by an empty template, which is essentially well, pretty empty indeed. It only contains a grid, and even that’s gonna go.

Delete the Grid

Add a Rectangle to the template by double clicking on the Rectangle button from the Assets toolbar on the left

This is a good moment to turn on Split View in the designer, because that shows you what the designer is actually doing. Right-click the rectangle in the Objects and Timeline panel, and select “View XAML”. At this point you will see only this:

And the design surface will only show a horizontal white rectangle with a black border.Default control sizeFirst and foremost, set the default size of your control. To get this done, look right top, select the Resources tab and expand App.Xaml. Then proceed as follows:

This will set the width and height of the rectangle to the full width and height of the control. If the user does not set a specific width and height, the values in the default Setters (both 40) will be used. XAML at this point:

Including the image as an ‘opacity mask’Blend’s greatest asset – it’s enormous capabilities – unfortunately is also sometimes its Achilles’ heel: there’s a bewildering set of options that’s not always easy to find your way in. Fortunately, at the top of the Properties there’s a Search box that helps you find that hard-to-find-options. Which is extremely helpful – if you happen to know what to look for ;-). In this case:

Your design surface should now looks like to the image to the left, which is kinda crummy. You can use the little triangle on the right bottom, and the two little lines on the right and the bottom, to resize the design surface. This will have no effect on the control template itself, it will make just make it look better (see right image) .
You can also manually add the attributes d:DesignWidth="75" and d:DesignHeight="75" to the Rectangle.Defining Visual StatesA CheckBox has certain states, the most obvious being Checked and Unchecked. Actually there are quite a lot more, and you can see them by clicking on the “States” tab. Now all these states are defined, but there are no visuals connected to it anymore, since you have replaced the control template by something empty and started filling in yourself. This next step will bring a bit of those visual states back. To prepare for that:

Make sure the Rectangle is selected in the “Objects and Timeline” panel left

In the Properties panel to the right of the screen, scroll down to “Transform”

In the “States” panel, click on the “Checked” state. This will add quite some XAML code: you will see a “VisualStateManager.VisualStateGroups” tag appear, defining all three states of the “CheckStates” group, i.e. “Checked”, “Unchecked” and “Indeterminate”.

Now Select the “Unchecked” state

Make sure the “Rectangle” still is selected in the “Objects and Timeline” panel

Select the “Properties” tab on the top right again

Select the (now green) “Fill” Rectangle again.

In the box where you previously typed “Green” (which will say ”#FF008000” now), type “Red”. The thumbs-up image will now turn red

Scroll down to “Transform” again

Select the right most tab

Select the “Flip Y-axis” button, in the middle. The thumbs-up image will now flip vertically and turn into a thumbs-down picture.

Locate the little red button on top of the design pane that says “Unchecked state recording is on”. Click it and the text should change into “Unchecked state recording is off”.

If you press F5, the project will compile and run (yes, that works from Blend as well), and you will see that the checkbox shows a green thumbs-up image when selected, and a red thumbs-down image when unselected.
Now, for a finale to make things a little more visually appealing:

Go back to the “States” tab again

Select the Textbox with “0 s” in the “Default transition” panel above state “Unchecked”

Type 0.5 in the text box

And press F5 again.

You will now see the thumbs not simply flip: now it rotates in half a second and change color from red via orange to green. By simply specifying a time you tell the application to actually infer an animation. And there you are. A completely customized, animated, thumb-up-thumbs-down control with just some clicking around. Code-wise it behaves just like a normal checkbox. And if you want to make more of these checkboxes, just select a standard CheckBox, right click it, Select “Edit template/Apply Resources/Thumbupdowncheckboxstyle” and boom – yet another Thumbup-thumbsdown control.
Final XAML:

You could of course go on and define all other states, but this already works pretty well IMHO ;-). Oh and by the way: this should work on any XAML platform, not just on Windows Phone. And for those who don’t like typing or copy-and-pasting, here is, as always, the complete demo solution.
Thanks to Willem Meints for helping me out via twitter on default setters for styles.

This whole article actually boils down to one line of code, but I need to go trough some hooplah to show you how to use it. It all begins with the data. Consider this piece of quite readable JSON, describing a few recent Windows Phone models.

JSON is rather compact, which is a great feature when you are developing for mobile devices. It has also a few downsides as far as client programming is concerned:

generating client code for it that does all the parsing and calling, as for SOAP, is not a standard feature of Visual Studio,

it’s almost impossible to read for an ordinary human being,

deciphering it into classes is a lot of work,

hand coding a parser for it is not fun.

Which is why you don’t. There are several ways of generating classes from JSON, the simplest way is this website: json2csharp by Jonathan Keith. You copy a JSON result into the upper textbox, hit the “Generate” button and out come your classes:

There are more sites that do the same, by the way, but this is what I use. Next steps:

Fire up Visual Studio

Create a new Windows Phone project (for instance JsonDemo)

Plonk the classes generated above in the project. Bonus cookies if you split them in separate files and add namespaces to them. Bonus donut if you, like me, think “RootObject” is actually a pretty ugly name for an object - so change it to "Phone".

Click Tools/Library Package Manager/Manage NuGet Packages for Solution (you do have the NuGet Package Manager installed, don’t you? If not, stop whatever you are doing now and get it right this instance, you hear me ;)? )

Search for JSON.Net

Click install. This will add a reference to NewtonSoft.Json.dll to your product.

Add references to Microsoft.Phone.Reactive and System.Observable because they are going to be needed in the next step.

To make the result visible, add some XAML to the default content panel in Mainpage.Xaml – just a button and a templated ListBox, no rocket science here:

And there it is, the one line of code that this is all about. Call the DeserializeObject method, template it with the return type you want, and stuff the JSON string in it. Result: a list of objects with their properties filled, even if there are things like nested objects (specs in these case) and arrays in there.

If you run the demo solution you get the result displayed in the image on the right. Keep in mind this code is by no means Windows Phone specific. There are JSON.Net implementations for virtually all frameworks available. So should you feel the need to use this from Silverlight or full .NET: it’s there.

You should, by the way, pay attention to the structure of the JSON. The code I show works for a list. A list in JSON starts with a square bracket: [. If your JSON starts with a curly brace: { then you get returned a single object - a so called root object. In that case, your deserialization should code return a single object in stead of a list as well, i.e. something like

This plug-in replacement for WebClient by Morten Nielsen adds support for GZIP compressed web requests – this reduces network traffic even further, apparently boosting load performance significantly. You won’t really notice the difference on such a small data files as used in this sample, but as your JSON return values get larger, so will be the impact of using this library.

For the record: I am not ill nor do I have forsaken MVVM, but I tried to make the example as simple as possible so yes, I used a little code behind, as to not to cloud the solution in architectural frills. ;-)

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.