Format WPF Bindings With Resource File Lookups
This post explains a pattern that combines Data Binding, the new StringFormat property and resource lookups through the application of a custom MarkupExtension.
StringFormat
Microsoft introduced the StringFormat property with SP1 for .NET 3.5. StringFormat often eliminates the need for a custom converter if you just need to format a bound value.
Here’s a very simple sample that displays hello xxx on the screen (where “xxx” is the value entered in a TextBox control:
<TextBox x:Name="name" Text="world" /> <TextBlock Text="{Binding ElementName=name, Path=Text, StringFormat=hello {0}}" />
Resource Files
I often use resource files to store strings – not only for localization tasks but also in order to maintain strings that are intended for users at a central place. My resource strings often contain placeholders which are populated at runtime using String.Format:
//use resource file to create message var msg = Resources.Ask_Whether_To_Connect_To_New_Share; msg = String.Format(msg, configuration.Name); //display dialog MessageBoxResult doConnect = Dialogs.ShowYesNo(msg);
Bringing Bindings and Resource Files Together
In the sample above, I accessed the resource file programmatically. In XAML however, I prefer a declarative approach. In order to get there, I implemented a simple MarkupExtension that allows me to do just that:
<!-- Display a formatted text --> <TextBlock x:Name="Title" Text="{Binding Path=Name, StringFormat={ext:Resource Ask_Whether_To_Connect_To_New_Share}}"
/>
The above snippet results in a formatted text being displayed:
Resource MarkupExtension
Here’s the markup extension. As you can see, it’s fairly trivial. Do note that the reference to the application’s Resources file is hardcoded – you will have to set a using statement or adjust that line in order to use your custom resource file.
/// <summary> /// A markup extension that provides simple access to a given /// entry in the application's <see cref="Resources"/> file. /// </summary> public class Resource : MarkupExtension { /// <summary> /// The resource key to be used for the lookup. /// </summary> public string ResourceKey { get; set; } /// <summary> /// Inits the <see cref="Resource"/> markup extension /// with the key to be assigned. /// </summary> /// <param name="resourceKey">The resource key to be assigned.</param> public Resource(string resourceKey) { ResourceKey = resourceKey; } /// <summary> /// Performs a lookup for the defined <see cref="ResourceKey"/>. /// </summary> /// <returns> /// The value of the resource that is specified by the /// <see cref="ResourceKey"/> property. If the property is not /// set, a null reference is returned. /// </returns> public override object ProvideValue(IServiceProvider serviceProvider) { if (String.IsNullOrEmpty(ResourceKey)) return null; return Resources.ResourceManager.GetObject(ResourceKey); } }
Enjoy 🙂