XAML Applications on Windows 8 with DXTREME
XAML Applications on Windows 8 with DXTREME
The public release date of Windows 8 is rapidly approaching and with it comes a brand new way to build and sell Windows applications via the new Windows Store.
I first used the new Windows Store platform earlier this year when I ported my open source Json.NET library to it, and since then I have also built a couple Windows applications on it using JavaScript. In this blog post I am trying out something new to me for the first time: Windows 8 development using .NET and XAML with DXTREME’s XAML controls.
Installation and first impressions
The first thing you’ll notice after downloading DXTREME is its installer. The design is simple and to the point, and it looks completely at home in the Windows 8 UI.
After installation is complete you are presented with a dialog that serves as a hub to developers getting started with DXTREME. The dialog links to two Visual Studio solutions: a demo application that shows off the Windows 8 XAML controls that come with the library, and a solution application that shows the controls used together in a great looking professionally designed Windows 8 app.
As someone completely new to DXTREME and Windows 8 XAML development I found both of these applications and their source code to be great resources when building my first Windows Store XAML app. Especially useful was a feature of the demo application that lets you view the source code for a control while the demo is running.
Getting Started
I find the best way to learn something new is to make something with it. The Windows 8 application I’m going to step through making in this blog post is called /r/Imgur and is an app that integrates the popular social websites Reddit and Imgur. It displays images from those websites within a Windows application. (a link to the final source code will be at the end of the blog post)
As part of its installation DXTREME adds new Windows 8 project types to Visual Studio 2012. I used the DXTREME Grid Application project which sets up a basic Windows 8 tile based UI for you using DXTREME’s new controls.
Fetching Data from Imgur
The application’s data and images are driven from Imgur, an Internet image hosting service. They provide a simple API for getting album information as JSON for their website.
public static async Task<Album> LoadAlbum(string subReddit)
{
Album album = new Album();
album.Title = subReddit;
HttpClient httpClient = new HttpClient();
string json = await httpClient.GetStringAsync("http://imgur.com" + subReddit + "/top.json");
JObject o = JObject.Parse(json);
foreach (JToken i in o["data"])
{
Image image = i.ToObject<Image>();
image.Album = album;
image.ImageUrl = string.Format("http://i.imgur.com/{0}.jpg", image.Hash);
album.Items.Add(image);
}
return album;
}
The code above utilizes the Web API Client library and Json.NET. It simply gets the album data as JSON and deserializes it to an Album object. These albums and their images are what the UI databinds to.
Styling the UI
Two of XAML’s most powerful features are its support for the model-view-view-model pattern (MVVM) and design time view data, both of which have great support in DXTREME. Once setup design time view data lets you style your Windows 8 application from within Visual Studio 2012 or Expression Blend against pretend data. You no longer need to constantly restart your application to see what the final result will be because it is instantly visible in the XAML designer. It’s a great timesaver.
The screenshot above is /r/Imgur in Expression Blend after I have finished styling it. The controls are being databound to hardcoded view model of Albums that I have created so that the look of the final application is visible in the Blend and Visual Studio designers without having to call off to the Imgur API.
Adding New Albums
As well as displaying some pre-set albums in the app we want to give users the ability to add new albums. To do this we’ll add a Windows 8 appbar button that will launch a Windows 8 style dialog with fields for the user to enter the new album name. Fortunately DXTREME has a Windows 8 style dialog that is perfect for the task.
<Page.Resources>
<DataTemplatex:Key="AddAlbumTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinitionWidth="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlockText="/r/"FontSize="18"VerticalAlignment="Center" />
<TextBoxGrid.Column="1"Text="{Binding Path=Title, Mode=TwoWay}"BorderThickness="1"BorderBrush="#FF3D3D3D"Margin="5 0 0 0" />
</Grid>
</DataTemplate>
</Page.Resources>
<dxcore:Interaction.Behaviors>
<dxcore:ServiceContainerBehaviorServicesClient="{Binding}">
<dxcore:DialogServiceKey="addDialog"ContentTemplate="{StaticResource AddAlbumTemplate}"Buttons="OKCancel"DefaultDialogButton="OK"CancelDialogButton="Cancel"Title="Add Reddit Album"/>
</dxcore:ServiceContainerBehavior>
</dxcore:Interaction.Behaviors>
Wiring up a DialogService to a DataTemplate using the code above lets you launch a dialog without having to worry about recreating the look and feel of a Windows 8 dialog; that’s all handled for you by the dialog control.
Album Rating
The final piece to the application is to add the album rating to its detail page. Here we’ll add a pie graph using DXTREME’s graphing library to display the ratio of user up votes to down votes for the album.
The look and behaviour of the pie graph is defined in XAML, allowing us to design it inside the Visual Studio XAML designer without running the application, and then the up and down votes for the album are databound the graph when the application executed at runtime.
Wrapping Up
I found the controls I used while making /r/Imgur well thought out and easy to use. One important feature I always look for in controls and libraries when using XAML is how well they work with the rest of the framework. Everything has great MVVM support and the controls included in the library provide a nice experience to work with the Visual Studio 2012 and Expression Blend designers.
Click here to download the /r/Imgur application source code
Disclosure of Material Connection: I received one or more of the products or services mentioned above for free in the hope that I would mention it on my blog. Regardless, I only recommend products or services I use personally and believe my readers will enjoy. I am disclosing this in accordance with the Federal Trade Commission’s 16 CFR, Part 255: Guides Concerning the Use of Endorsements and Testimonials in Advertising.
Json.NET 4.5 Release 10 – Portable Class Library on NuGet
Json.NET's major new feature this release is the portable class library assembly is available over NuGet. This is made possible by NuGet 2.1 supporting portable class libraries. Read more about NuGet 2.1 here.
Case insensitive JObject GetValue and TryGetValue
To simplify getting property values without worrying about the property name's case a couple of helper methods have been added to JObject. GetValue and TryGetValue will first attempt to get a property value with the exact case after which it will ignore case and the first matching property will be returned.
JObject o = JObject.Parse(@"{
'name': 'Lower',
'NAME': 'Upper'
}");
string exactMatch = (string)o.GetValue("NAME", StringComparison.OrdinalIgnoreCase);
// Upper
string ignoreCase = (string)o.GetValue("Name", StringComparison.OrdinalIgnoreCase);
// Lower
In this example the first call to GetValue with "NAME" exactly matches the second property. The second call to GetValue with "Name" doesn’t exactly match any of the properties so a case insensitive search is made and the first property is returned.
Changes
Here is a complete list of what has changed since Json.NET 4.5 Release 9.
- New feature - Added Portable build to NuGet package
- New feature - Added GetValue and TryGetValue with StringComparison to JObject
- Change - Improved duplicate object reference id error message
- Fix - Fixed error when comparing empty JObjects
- Fix - Fixed SecAnnotate warnings
- Fix - Fixed error when comparing DateTime JValue with a DateTimeOffset JValue
- Fix - Fixed serializer sometimes not using DateParseHandling setting
- Fix - Fixed error in JsonWriter.WriteToken when writing a DateTimeOffset
- Fix - Fixed error when serializing emitted classes that have null constructor parameter names
- Fix - Fixed empty strings not correctly deserializing as null onto nullable properties
Links
Json.NET 4.5 Release 10 Download – Json.NET source code and assemblies
Json.NET vs Windows.Data.Json
Windows 8 introduces a new way to work with JSON via the Windows.Data.Json namespace. Similar to LINQ to JSON in Json.NET it defines classes that can be used to parse values, strings, objects, and arrays from JSON text or serialize value types into JSON text.
Below is a comparison of Json.NET’s LINQ to JSON to Window 8’s Windows.Data.Json.
Creating JSON
The big difference between the two libraries when creating JSON is Windows.Data.Json requires string/integer/double values to be explicitly converted to JsonValue objects.
Note that there is a weird limitation to creating JSON with Windows.Data.Json: it doesn’t allow you to set properties to null or have null array values.
// Windows.Data.Json
// -----------------
JsonObject jsonObject = new JsonObject
{
{"CPU", JsonValue.CreateStringValue("Intel")},
{"Drives", new JsonArray {
JsonValue.CreateStringValue("DVD read/writer"),
JsonValue.CreateStringValue("500 gigabyte hard drive")
}
}
};
string json1 = jsonObject.Stringify();
// LINQ to JSON
// ------------
JObject jObject = new JObject
{
{"CPU", "Intel"},
{"Drives", new JArray {
"DVD read/writer",
"500 gigabyte hard drive"
}
}
};
string json2 = jObject.ToString();
Querying JSON
Windows.Data.Json requires a value to be cast to its exact type with the GetObject/GetArray methods before it can be used, making Windows.Data.Json’s code verbose compared to LINQ to JSON.
string json = @"{
""channel"": {
""title"": ""James Newton-King"",
""link"": ""http://james.newtonking.com"",
""description"": ""James Newton-King's blog."",
""item"": [
{
""title"": ""Json.NET 1.3 + New license + Now on CodePlex"",
""description"": ""Annoucing the release of Json.NET 1.3, the MIT license and the source being available on CodePlex"",
""link"": ""http://james.newtonking.com/projects/json-net.aspx"",
""category"": [
""Json.NET"",
""CodePlex""
]
}
]
}
}";
// Windows.Data.Json
// -----------------
JsonObject jsonObject = JsonObject.Parse(json);
string itemTitle1 = jsonObject["channel"].GetObject()["item"].GetArray()[0].GetObject()["title"].GetString();
// LINQ to JSON
// ------------
JObject jObject = JObject.Parse(json);
string itemTitle2 = (string)jObject["channel"]["item"][0]["title"];
Performance
Json.NET is slightly slower at writing JSON than Windows.Data.Json but considerably faster parsing.
Converting Between LINQ to JSON and Windows.Data.Json
Json.NET supports converting between the types of the two libraries. Use FromObject to convert a Windows.Data.Json value to LINQ to JSON and use ToObject to convert LINQ to JSON to Windows.Data.Json.
JsonObject jsonObject = new JsonObject
{
{"CPU", JsonValue.CreateStringValue("Intel")},
{"Drives", new JsonArray {
JsonValue.CreateStringValue("DVD read/writer"),
JsonValue.CreateStringValue("500 gigabyte hard drive")
}
}
};
// convert Windows.Data.Json to LINQ to JSON
JObject o = JObject.FromObject(jsonObject);
// convert LINQ to JSON to Windows.Data.Json
JArray a = (JArray)o["Drives"];
JsonArray jsonArray = a.ToObject<JsonArray>();
Json.NET 4.5 Release 8 – Multidimensional Array Support, Unicode Improvements
Multidimensional Array Support
Json.NET now supports serializing and deserializing multidimensional arrays. There isn't anything you need to do, if one of your types has a multidimensional array property It Just Works™.
string[,] famousCouples = new string[,]
{
{ "Adam", "Eve" },
{ "Bonnie", "Clyde" },
{ "Donald", "Daisy" },
{ "Han", "Leia" }
};
string json = JsonConvert.SerializeObject(famousCouples, Formatting.Indented);
// [
// ["Adam", "Eve"],
// ["Bonnie", "Clyde"],
// ["Donald", "Daisy"],
// ["Han", "Leia"]
// ]
string[,] deserialized = JsonConvert.DeserializeObject<string[,]>(json);
Console.WriteLine(deserialized[3, 0] + ", " + deserialized[3, 1]);
// Han, Leia
Unicode Performance Improvements
Prior versions of Json.NET allocated a new array and string object to the heap for every Unicode character; a potentially expensive situation if your application is writing a lot of Unicode characters.
This release improves Unicode serialization so that Json.NET will only allocate a single array for all Unicode text and then writes the text directly to the underlying output stream. These changes improve Json.NET performance of Unicode intensive objects by about 20% and significantly reduces the time spent doing garbage collection.
Changes
Here is a complete list of what has changed since Json.NET 4.5 Release 7.
- New feature - Serialize and deserialize multidimensional arrays
- New feature - Members on dynamic objects with JsonProperty/DataMember will now be included in serialized JSON
- New feature - LINQ to JSON load methods will read past preceding comments when loading JSON
- New feature - Improved error handling to return incomplete values upon reaching the end of JSON content
- Change - Improved performance and memory usage when serializing Unicode characters
- Change - The serializer now creates objects using GetUninitializedObject when deserializing a Serializable type
- Fix - Added SecurityTransparent attribute to WinRT build
- Fix - Fixed infinite loop error caused by error handling upon reaching the end of JSON content
Links
Json.NET 4.5 Release 8 Download – Json.NET source code and assemblies