Binding to a ConverterParameter in Windows 8 Metro

This article describes how to simulate databinding to a ConverterParameter in a Windows 8 Metro XAML app. Let's say we have a TextBlock that displays a value from the ViewModel, and a Converter that takes this value together with some Range object as parameter. The converter should return a Brush -green or red- that indicates wether or not the value is within the range. The converter is used for providing the foreground color of the textblock. The following intuitive code would represent this behavior:

<TextBlock 
     Text="{Binding SomeValue}" 
     Foreground="{Binding SomeValue, Converter={StaticResource RangeValidationConverter}, ConverterParameter={Binding SomeRange}}" />

Unfortunately, databinding to a ConverterParameter is not supported by any of Microsoft's XAML platforms. But let me share with you a little secret: that binding is actually easy to simulate. The following screenshots from the attached sample application show the bitterness of a beer (a value from the ViewModel) in green if it's within the expected range (the alleged Range parameter for the Converter), and red if it's out of range. With the slider you can throw more hops into the recipe to add bitternes, or remove hops to decrease bitterness. The value in the textblock, the needle in the gauge, but also the color of the textblock will synchonize with the bitterness value:

Here's how it works. Instead of using the converter parameter, I decorated the converter with a dependency property to hold the range:

public Range<int> Range
{
    get { return (Range<int>)GetValue(RangeProperty); }
    set { SetValue(RangeProperty, value); }
}

public static readonly DependencyProperty RangeProperty =
    DependencyProperty.Register("Range", typeof(Range<int>), typeof(RangeValidationConverter), new PropertyMetadata(new Range<int>(0,100)));

The converter can use the Range in its Convert method:

public object Convert(object value, Type targetType, object parameter, string language)
{
    int measurement = System.Convert.ToInt32(value);

    Range<int> range = this.GetValue(RangeProperty) as Range<int>;

    if (range == null)
    {
        return new SolidColorBrush(Colors.Gray);
    }

    if (measurement >= range.Min && measurement <= range.Max)
    {
        return new SolidColorBrush(Colors.LawnGreen);
    }

    return new SolidColorBrush(Colors.Red);
}

The converter is registered in the traditional way: as a resource. But the Range property can now be assigned through data binding:

<Page.Resources>
    <local:RangeValidationConverter 
        x:Key="RangeValidationConverter"
        Range="{Binding BitternessRange}" />
</Page.Resources>

 The textblock just uses the converter without providing a parameter:

<TextBlock 
    Text="{Binding CurrentBitterness}"
    Foreground="{Binding CurrentBitterness, Converter={StaticResource RangeValidationConverter}}" />

There you go !

Here's the source code. It was written in Visual Studio 11 Express Beta for the Windows 8 Consumer Preview: U2UC.Metro.ConverterParameterBinding.zip (115,27 kb)

Enjoy!