IValueConverter in WPF data binding

One of the handy things that you can do with data binding in WPF is that you convert the data as you pull it from the data source. The mechanism for this is the IValueConverter interface.
 
Let's say that you have a list of numbers representing positions in a race, and you want to display this list with the appropriate positional text (for example, 1 is 1st, 2 is 2nd, 3 is 3rd, etc). Rather than save your data in this form (which would not be convenient at all) you could leave the data as an int in the data source, and write a value converter to convert the integer into the appropriate string. This has many benefits - for example, if the UI is being virtualized, then only the items that have been created will be converted. And if the position changes WPF takes care of updating the string.
 
The first step is to make a class deriving from IValueConverter. We will call our class PositionConverter. There are two interface members - one of them to convert to the target type, and one of them to convert back. We don't need to convert back, so we just need to implement ConvertTo:

public class PositionConverter : IValueConverter

    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

        {

            if (value != null)

            {

                int number = (int)value;

                string numberText = number.ToString();

                string positionText;

                if (number >= 10 && numberText[numberText.Length - 2] == '1')

                {

                    // teen numbers always end in 'th'

                    positionText = "th";

                }

                else

                {

                    switch (numberText[numberText.Length - 1])

                    {

                        case '1':

                            positionText = "st";

                            break;

                        case '2':

                            positionText = "nd";

                            break;

                        case '3':

                            positionText = "rd";

                            break;

                        default:

                            positionText = "th";

                            break;

                    }

                }

                return (numberText + positionText);

            }

            return string.Empty;

        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

        {

            throw new Exception("The method or operation is not implemented.");

        }

    }

To use the converter we can create one in the resources section of the window, and refer to it as a static resource in the binding statement:

<Window x:Class="ValueConverterDemo.Window1"

  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"

  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"

  xmlns:local="clr-namespace:ValueConverterDemo"

  Title="ValueConverterDemo"

  Height="300"

  Width="300">

  <Window.Resources>

    <local:PositionConverter x:Key="PositionConverter" />

  </Window.Resources>

  <ListBox Name="numberBox">

    <ListBox.ItemTemplate>

      <DataTemplate>

        <TextBlock Text="{Binding Converter={StaticResource PositionConverter}}" />

      </DataTemplate>

    </ListBox.ItemTemplate>

  </ListBox>

</Window>

Now the numbers show up with positional text in them (45 becomes 45th, for example).

Value converters are very useful tools for letting you use the power of data binding. You can even pass parameters to them, so that you can combine data in the value converter.

Next up I show what ConvertBack is used for.