At MIX11 today, Silverlight 5 beta was released. It includes a whole load of new features (most of which were already known by people who watched the Firestarter event last December), you can find the full list at Tim Heuers’ blog.
One of the small, yet pretty interesting additions in my opinion are Markup Extensions. Tim quickly mentions it, but there’s no example to be found on Silverlight.NET, so I figured: why not try it out myself? 🙂
With custom markup extensions, you can in essence execute your own code instead of the default Binding markup extension, which will provide the correct desired value for the property you’re using the markup exension for. One of the typical uses for this could be for multi-language apps: getting the correct text in the correct language from your resource dictionaries.
Up until now, I had to provide quite a bit of code to enable my app to handle multiple languages: I would typically create some kind of resource wrapper, make that available through App.XAML or a resource dictionary, reference the resource on all my Views and bind to the resource wrapper + resourceKey property of that wrapper.
With markup extensions, this becomes a lot easier. Start out by creating a new SL project, and add 2 resx-files: one default, one with the .nl extension for Dutch translations. Then, add a new class to your project, and make it implement the IMarkupExtension<T> interface, where T is the type of object you want to get back from the code. In that class, you can add a bunch of properties, methods, … to your liking. In this case, all I need is a string property, ResourceKey. The ProvideValue method is what gets executed to get the desired value, which, in this case, comes down to getting the translation with key ResourceKey from the resx file. That’s no more than a few lines of code:
public class TranslationExtension : IMarkupExtension<string> { public string ResourceKey { get; set; } public string ProvideValue(IServiceProvider serviceProvider) { // get the ResourceKey value from translations return SL5MarkupExtensions.TranslationResources
.Translations.ResourceManager.GetString(ResourceKey);
}
}
Next, we need to use this in XAML. Import the correct namespace, and call the Markup Extension from XAML, passing in the ResourceKey parameter:
<TextBlock Text="{me:TranslationExtension ResourceKey=DemoResourceKey}"/>
And… that’s it. Really. Instead of having to create all I described in the beginning, all I need are these few lines of code. To check if it still works when changing the language, I added a button which will set the culture to “nl”, and navigate to another View, containing a TextBlock using the markup extension with the same ResourceKey.
This is one really short example to show you how easy it is to use markup extensions, but I ‘m pretty sure you can already see how it can prove useful. For example, you might use it to get the correct ViewModel for your View, if you’re using MVVM.
By the way, in case you’re wondering why I’m navigating to another View: I want to make sure the markup extension code gets executed again. If you want true on-the-fly language changing in your app, you’ll have to provide a way to notify your app it should re-execute the extension. This goes beyond the point of this blog post, but there already are quite a few implementations for this available for WPF, like this one, which should be easy to port if you really need it.
That’s it! You can download the source code here. Happy coding! 🙂