Three things you probably didn’t know about XAML converters #3: A better ValueInverter

In the previous post I discussed two ways of passing parameters to XAML ValueConverters, for example to allow inverting boolean values without creating a separate converter containing redundant code snippets. How to handle parameters in combination with converters is a good thing to know of course, but the whole Inverter thing can certainly be improved. Typically, when data-binding XAML properties to inverted boolean values, you would either duplicate the whole converter in question and add a negation somewhere inside the converter logic, or create parameterized versions as presented in the previous post – both solutions end up with a lot of redundant code, since you do the same things over and over again, repeated in each project.

A simple boolean ValueInverter:

Therefore I came up with a totally different approach: The BooleanValueInverter that wraps around any other ValueConverter and inverts either the input or the output value of this converter, before returning the final result for data-binding. A basic boolean inverter is easy to implement – just ensure that the input value is of type bool, invert it (which is the shortest code snippet ever, thanks to the C# ! command!) and return it:

public class BooleanValueInverter : IValueConverter
{
	public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
	{
		if (value is bool)
			return !(bool) value;
		else
			return DependencyProperty.UnsetValue; // Fallback for non-boolean input values
	}

	public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
	{
		throw new NotImplementedException();
	}
}

Inverting other converters:

That’s it for boolean values that are to be bound to boolean properties – but what about other types, such as the infamous Visibility enumeration, as returned by the typical BooleanToVisibilityConverter that is used in virtually every XAML project? Well, in this case the idea is to use the BooleanValueInverter as wrapper that automatically executes the BooleanToVisibilityConverter after inverting the boolean input value. And since this might be useful to wrap around other types of ValueConverters also, we won’t hard-code the converter to be used internally, but instead provide the option of passing one! (Since the possibility of passing a ConverterParameter is rather inflexible and therefore not regularly used as discussed in my previous post, this might actually be an approach of how to use the ConverterParameter field in a useful way!)

public class BooleanValueInverter : IValueConverter
{
	public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
	{
		if (!(parameter is IValueConverter))
		{
			// No second converter is given as parameter:
			// Just invert and return, if boolean input value was provided
			if (value is bool)
				return !(bool) value;
			else
				return DependencyProperty.UnsetValue; // Fallback for non-boolean input values
		}
		else
		{
			// Second converter is provided:
			// Retrieve this converter...
			IValueConverter converter = (IValueConverter) parameter;

			if (value is bool)
			{
				// ...and invert and then convert boolean input value!
				bool input = !(bool)value;
				return converter.Convert(input, targetType, null, culture);
			}
			else
			{
				return DependencyProperty.UnsetValue; // Fallback for non-boolean input values
			}
		}
	}

	public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
	{
		throw new NotImplementedException();
	}
}

This code snippet should also be easy enough to understand: In addition to the simple Inverter presented above, here we first check if any IValueInverter instance has been passed – if yes, we execute this converter on the inverted boolean input value, otherwise we just return the inverted input value as above.

To use such an inverter in XAML, register it and the converter it shall execute as static resource:

<Page.Resources>
	<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
	<BooleanValueInverter x:Key="Inverter" />
</Page.Resources>

…and reference them within a data binding attribute:

<Button Visibility="{Binding MyFlag, Converter={StaticResource Inverter}, ConverterParameter={StaticResource BooleanToVisibilityConverter}}" />

And now the other way round…

Of course, there is always room for improvement – for example, what about converters that return a boolean value that is calculated from any other data type, and not the other way round like BooleanToVisibilityConverter? An example would be some kind of StringLengthToBooleanConverter that returns true only if a given text value contains at least one character – I use such an implementation regularly to bind some button’s IsEnabled property to a TextBox such that the button is only enabled if some text has been entered into the text box. This requires only a few additions to the code snippet shown above – a third branch is added that executes the given converter first (if the input value is not of type bool), and then inverts this converter’s result, assuming that this is a boolean value! Here is the full BooleanValueInverter class:

public class BooleanValueInverter : IValueConverter
{
	public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
	{
		if (!(parameter is IValueConverter))
		{
			// No second converter is given as parameter:
			// Just invert and return, if boolean input value was provided
			if (value is bool)
				return !(bool) value;
			else
				return DependencyProperty.UnsetValue; // Fallback for non-boolean input values
		}
		else
		{
			// Second converter is provided:
			// Retrieve this converter...
			IValueConverter converter = (IValueConverter) parameter;

			if (value is bool)
			{
				// ...if boolean input value was provided, invert and then convert
				bool input = !(bool)value;
				return converter.Convert(input, targetType, null, culture);
			}
			else
			{
				// ...if input value is not boolean, convert and then invert boolean result
				object convertedValue = converter.Convert(value, targetType, null, culture);
				if (convertedValue is bool)
					return !(bool) convertedValue;
				else
					return DependencyProperty.UnsetValue; // Fallback for non-boolean return values
			}
		}
	}

	public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
	{
		throw new NotImplementedException();
	}
}

If you find this code useful, feel free to copy and use it in your projects, but keep in mind that for Windows Store Apps the IValueConverter interface looks a little bit different, there you need to replace CultureInfo culture by string language and of course also all its references in the code.

I’ve also published three implementations for WPF, Windows Phone and Windows Store as a small library available on Nuget that you can reference in any of your projects – find the Nuget link here or type

PM> Install-Package BooleanValueInverter

into your package manager console to download and install it! The package contains libraries for WPF .NET 4.0 / 4.5+, Windows Phone 7.1 / 8.0+ and Windows Store projects.