Posted Sunday, May 19, 2013 by Nigel Sampson
Often in your view models you’ll need to indicate to the view that some work is happening. In fact I would mandate it, for low powered Windows RT devices. These add to the idea of “perceived performance” in that something on the screen reacts immediately to the users touch and they’re not mashing the screen wondering if it’s working.
I typically make a distinction between Loading and Working. For me Loading is creating, requesting the data that the view presents and would normally be indicated by a Progress Ring in the part of the view this data would be normally shown. Working tends to come after this when the user is acting on the data already loaded, such as Closing an Issue in Hub Bug which I tend to use a Progress Bar across the top of the app (much akin to the Progress Indicator in Windows Phone which tends to get used for both).
There’s a lot of different ways to approach this problem, some people use visual states others use simple Boolean properties on their view models. One thing I found myself doing a lot was starting the working or loading indicator but forgetting to stop it. Admittedly this was pre async / await where you had to bury the stop code in a lambda or callback.
I’ve found using (abusing?) the using statement with disposables to create Loading or Working blocks is a nice way to structure view models so it’s very easy to see how that UI is affected by the view model.
The first thing we need is a little helper class named DisposableAction, this class simply implements IDisposable and takes an Action. When the class is disposed it calls the Action.
public class DisposableAction : IDisposable
{
private readonly Action action;
public DisposableAction(Action action)
{
this.action = action;
}
public void Dispose()
{
action();
}
}
For this example I’ll just a Boolean property IsLoading that’s hypothetically bound to the visibility of a Progress Ring. We’ll create a method calling Loading that first sets IsLoading to true and then returns an DisposableAction that sets it to false when it’s disposed.
protected IDisposable Loading()
{
IsLoading = true;
return new DisposableAction(() => IsLoading = false);
}
Now that we have our Loading method we can use it in loading our view model (in this case Caliburn.Micro's OnInitiated). Because Loading returns an IDisposable we can use the using statement to wrap our code and quickly visualise how the Loading.
protected override async void OnInitialize()
{
base.OnInitialize();
using (Loading())
{
await BindCategoriesAsync();
await BindProductsAsync();
}
}
Posted Tuesday, April 30, 2013 by Nigel Sampson
Linq is awesome, async / await is awesome, but combining them can be a little awkward. None of the standard linq operations are written to deal with async lambdas, this often leads to writing the async operations in a more procedural style approach rather than the functional one that Linq uses.
Here's a couple of useful extension methods I use, WhenAllAsync allows you to execute an aysnc method on a sequence of values. By using Task.WhenAll we can have the async method execute in parallel with each other.
public static Task WhenAllAsync<T>(this IEnumerable<T> values, Func<T, Task> asyncAction)
{
return Task.WhenAll(values.Select(asyncAction));
}
The usage is pretty self explanatory, the only odd bit is that because DeleteAsync returns an IAsyncOperation rather than Task we use AsTask to convert it (or if you want right a second extension method using IAsyncOperation).
var files = await GetFilesAsync();
await files.WhenAllAsync(f => f.DeleteAsync().AsTask());
SelectAsync is useful for transforming a collection of values to another type via an asynchronous method. It's much like WhenAllAsync except that we return the result of the operation.
public static async Task<IEnumerable<TResult>> SelectAsync<TSource, TResult>(this IEnumerable<TSource> values, Func<TSource, Task<TResult>> asyncSelector)
{
return await Task.WhenAll(values.Select(asyncSelector));
}
var images = await GetFilesAsync();
var streams = await files.SelectAsync(f => f.OpenAsync(FileAccessMode.Read).AsTask());
Hopefully these help you write more readable performant async code.
Posted Monday, April 22, 2013 by Nigel Sampson
C# 5 came with the Caller Information attributes, which are ways to mark up your code such that at compile time the values for these method parameters would be populated with the member name, file path and line number of the caller. The canonical use case for this a logging or tracing method like in the documentation.
The next obvious place is the property changed notifications that form the basis of binding in all the Microsoft Xaml frameworks. Pete Brown provides a good example of this with Using CallerMemberName for Property Change Notification in Xaml Apps.
So what’s some other ways we can use this? For application settings I often find myself creating a lot of properties that are simply strong wrappers around the platforms settings dictionary. You end up wiring in the key for the dictionary in a couple of places there’s a lot of ceremony over essence.
public class AppSettingsService
{
protected static readonly ApplicationDataContainer LocalSettings = ApplicationData.Current.LocalSettings;
public string Username
{
get
{
if (!LocalSettings.Values.ContainsKey("Username"))
return String.Empty;
return (string) LocalSettings.Values["Username"];
}
set
{
LocalSettings.Values["Username"] = value;
}
}
}
If we create generic Get and Set methods for these dictionaries we can use CallerMemberName as the key and have it automatically filled out by the compiler. To handle this I’ve created a JsonSettingsService for WinRT, it automatically handles serializing the types to json using Json.NET because the underlying container handles only simple types.
public class JsonSettingsService
{
protected static readonly ApplicationDataContainer LocalSettings = ApplicationData.Current.LocalSettings;
protected static T Get<T>(T defaultValue, [CallerMemberName] string key = "")
{
if (!LocalSettings.Values.ContainsKey(key))
return defaultValue;
var json = (string) LocalSettings.Values[key];
return JsonConvert.DeserializeObject<T>(json);
}
protected static void Set<T>(T value, [CallerMemberName] string key = "")
{
var json = JsonConvert.SerializeObject(value);
LocalSettings.Values[key] = json;
}
}
The Get method takes a default value and the key (annotated with CallerMemberName attribute), while the Set has the value to store and the key. Nothing particularly complicated here.
The usage is where it gets interesting, for my app I’ve created my settings service inheriting from JsonSetttingService, for this example I want to store the details of the current user exposed through our string property with the default value being an empty string. Now the property is simply the following, technically the defaultValue: label isn’t required but I feel it adds some readability to the code.
public class AppSettingsService : JsonSettingsService
{
public string Username
{
get
{
return Get(defaultValue: String.Empty);
}
set
{
Set(value);
}
}
}
I hope this gives you some ideas on some other ways you use the caller member information to your advantage.
Posted Thursday, April 18, 2013 by Nigel Sampson
A lot of people have recently asked about the libraries, tools and resources I use to build Windows 8 and Windows Phone applications so I’d like to cover off as many as I can. It’s not an exhaustive list but I wouldn’t approach an app without almost all of these being involved.
Libraries
Caliburn Micro Windows Phone, Windows 8, unless the app is a throw away prototype I always use Caliburn Micro as my MVVM framework of choice (I may be a little biased these days though). The conventions help in bringing down the amount of plumbing code you need and it can do as little or as much as you want with a huge number of configuration and extension points.
Akavache Windows Phone, Windows 8, a hidden gem from the guys and gals at GitHub. Every app should use some sort of local caching for performance reasons and Akavache makes this incredibly easy. For Windows 8 I’d recommend the SQLite backend.
Json.Net Windows Phone, Windows 8, so many API’s use JSON as the transfer format and Json.Net is one of the easiest libraries to use. Developed by fellow kiwi James Newton King.
Callisto Windows 8, a UI library from Tim Heuer that helps fills the gaps in the WinRT xaml controls collection. The Flyout and Menu controls are incredibly useful.
Telerik / Syncfusion / Mindscape Windows Phone, Windows 8, all the xaml platforms have third party control vendors. For Windows Phone I couldn’t go past Telerik, their portfolio of controls covers almost all of my requirements, one of the best ways to get these controls is to join the Nokia Developer program. On the Windows 8 side the pickings are a little slimmer thanks to the newness of the platform. I’d recommend looking over the libraries of Telerik, Syncfusion and Mindscape to find the set that best suits your needs.
Tools
XamlSpy Windows Phone and Windows 8, much like the DOM inspection tools present in all browsers these days XamlSpy lets you inspect the visuals of your xaml app at run time. I find it useful for testing alignments by overlaying a grid and for discovering where some surprising margins and paddings come from (I’m looking at you FlipView). To help get your app over the final quality hurdles I wouldn’t go for anything else.
Expression Design, while technically discontinued I’ve found Expression Design a nice tool for tweaking simple visual assets such as icons and logos. For people like me who find something like Photoshop a bit of overkill this may be useful.
Inkscape, one approach to get around the multiple image requirements for both Windows 8 and Windows Phone is to use vector paths in your app, these will scale to any size without losing detail or becoming pixelated. Inkscape is an svg tool that has a useful “Save to xaml” tool that comes in really handy.
Resources
Modern UI Icons Windows Phone and Windows 8, hands down the best iconography resource for all Modern UI (cough, Metro) apps. As every icon in png, xaml and design (for those of us who still use Expression Design) which is incredibly useful.
Color Hexa, while I certainly don’t have a particularly advanced design skillset it’s useful to be able to find appropriate colours. Color Hexa provides all the information about a given colour you’ll ever need. I use it to find different shades of a colour and to find it’s compliment for use as an accent colour for instance.
While this isn't an exhaustive list I hope it gives you an idea of some of the tools, libraries and resources out there that you can use.
Posted Monday, April 08, 2013 by Nigel Sampson
The Boolean to Visibility Converter is as close you’re going to get to bread and butter in the xaml frameworks. You need it in almost every app and almost every framework has one, even the Windows 8 project templates come with one.
The trouble is that a lot of these implementations are naïve and simplistic, and soon enough you’ll be writing “Inverse Boolean to Visibility Converter”, “Int32 to Visibility Converter” etc. Ultimately these all exhibit very similar behavior, convert the default value (false, 0, null etc.) to Collapsed and anything else to Visible or do the same but inversed. Having over a dozen converters for all the implementations becomes a pain to manage and awkward.
So let’s build the last Visibility Converter you’ll need, we’ve already defined what the behavior should be, “Convert the default value to Collapsed and everything else to Visible”. The first thing we need to do is determine the default value for a type. If the type is a value type (int, boolean etc.) then we create an instance of the type otherwise the type is a reference type so the default value is null. Below is an example of this as an extension method for WinRT.
public static object GetDefaultValue(this Type type)
{
return type.GetTypeInfo().IsValueType ? Activator.CreateInstance(type) : null;
}
Now we can create our converter, we’ll want to have two properties to customize the behavior, the first, Inverse is pretty simplistic, the second, SupportIsNullOrEmpty is to deal with the one exception to our rules above and that’s string. The default value for string is null but we’ll typically want to treat an empty string as null, so we’ll add a second property SupportIsNullOrEmpty to be able to turn on or off dealing empty strings as null (it’ll be on by default).
public class VisibilityConverter : IValueConverter
{
public VisibilityConverter()
{
SupportIsNullOrEmpty = true;
}
public bool Inverse
{
get;
set;
}
public bool SupportIsNullOrEmpty
{
get; set;
}
public object Convert(object value, Type targetType, object parameter, string language)
{
bool visible;
if (value is string && SupportIsNullOrEmpty)
{
visible = !String.IsNullOrEmpty(value.ToString());
}
else
{
var defaultValue = value != null ? value.GetType().GetDefaultValue() : null;
visible = !Equals(value, defaultValue);
}
if (Inverse)
visible = !visible;
return visible ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotSupportedException();
}
}
The only downside to this approach is that ConvertBack can’t be implemented sensibly but to be honest I’ve never found a reason to have a * to Visibility converter to need it (that’s not to say there aren’t some).