Solibulo

Uninteresting things

Silverlight 3 – Tip of the month #2 - Using Data Binding with Static Resources in Silverlight

by softlion 10. October 2009 13:06

 

In his blog, Pedro wrote a post showing how to bind a property to a static resource where the resource name is given by the binded property. But his solution needs WPF libraries and does not work in Silverlight.

This is the first way to write it which comes to mind. But it doesn’t work as StaticResource does not support Binding (it is static by nature).

<Image Source="{StaticResource {Binding AvailabilityStateResourceName}}" />

 

The solution I came with is elegant. It uses a custom converter to find the resource in the application resource dictionary. The binding source must be a string containing the name of the static resource.

 

<Image Source="{Binding AvailabilityStateResourceName, Converter={StaticResource StaticResourceConverter}}" />

 

To use it, declare a static resource refering to the converter like this:

<Application ...
             xmlns:shc="clr-namespace:Softlion.Silverlight.Shared.Converters;assembly=Softlion.Silverlight.Shared" 
             >
    <Application.Resources>
        <shc:StaticResourceConverter x:Key="StaticResourceConverter" />
        ...
    </Application.Resources>
</Application>

 

And the source code of the StaticResourceConverter which is simple and straightforward:

using System;
using System.Windows.Data;
using System.Windows;

namespace Softlion.Silverlight.Shared.Converters
{
    /// <summary>
    /// Enables a binding on a static resource in the application resource dictionary.
    /// Convert from a static resource name to a resource instance in the application resource dictionary.
    /// </summary>
    public class StaticResourceConverter : IValueConverter
    {
        #region IValueConverter Members
        /// <summary>
        /// Convert from a static resource name to a resource instance in the application resource dictionary.
        /// </summary>
        /// <param name="value">must be a reference to an existing resource in the application resource dictionary</param>
        /// <param name="targetType">defined by the resource</param>
        /// <param name="parameter">not used</param>
        /// <param name="culture">not used</param>
        /// <returns>A resource in the Application.Current.Resources dictionary</returns>
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (!(value is string))
                throw new ArgumentException("value");

            return Application.Current.Resources[value];
        }

        /// <summary>
        /// Not implemented, no use
        /// </summary>
        /// <param name="value"></param>
        /// <param name="targetType"></param>
        /// <param name="parameter"></param>
        /// <param name="culture"></param>
        /// <returns></returns>
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
        #endregion
    }
}