C# WPF Value Converters


Continuing with the example of the text box and the slider we are going to improve the program by ensuring that at most two decimal places are displayed in the text box. For a more complete example, see the post RGB Colour Viewer.

DataBindingConverters

A data converter is a special class you write that intercepts the data between the source and the target and that can manipulate it however you want. A data converter class must use the ValueConversion attribute and must implement the IValueConverter interface. The interface consists of two methods — Convert and ConvertBack.

<Window x:Class="TwoWayConverter.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TwoWayConverter"
        mc:Ignorable="d"
        Title="Converter" Height="150" Width="360">
    <StackPanel>
        <TextBox Margin="10">
            <TextBox.Text>
                <Binding ElementName="sldrSlider" Path="Value">
                    <Binding.Converter>
                        <!--  Above: Associate Converter with the Binding 
                        Below: Notice that you need to add the namespace of the
                        project to use the data converter class and then
                        associate the converter with the binding.  -->
                        <local:DisplayTwoDecPlaces/>
                    </Binding.Converter>
                </Binding>
            </TextBox.Text>
        </TextBox>
        <Slider Name="sldrSlider" TickPlacement="TopLeft" Margin="10"/>
    </StackPanel>
</Window>

The following data converter class, called DisplayTwoDecPlaces, is in a separate file called DisplayTwoDecPlaces.cs. The namespace of this project, in this particular case, is TwoWayConverter.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;  // add this for IValueConverter

namespace TwoWayConverter
{
    // You must specify the ValueConversion attribute in square brackets
    //           type of the source,type of the target
    [ValueConversion(typeof(double), typeof(string))]
    public class DisplayTwoDecPlaces  : IValueConverter
    {
        public object Convert(object value, Type targetType,
                object parameter, System.Globalization.CultureInfo culture)
        {
            double dValue = (double)value;
            return dValue.ToString("F2");
        }
        public object ConvertBack(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
        {
            double dValue;
            double.TryParse((string)value, out dValue);
            return dValue;
        }
    }   
}

Namespaces

If you want to use a .NET namespace that is not a XAML namespace, you must use a special syntax to tell the XAML parser you want to use a .NET namespace. .NET namespaces are called CLR namespaces. To specify a CLR namespace called, TwoWayConverter, which is declared in your project, you would use the following syntax.

xmlns:local="clr-namespace:TwoWayConverter"

For a namespace in your project, the prefix local is often used. Notice that the string being assigned to the prefix starts with the string clr-namespace:. This keyword string tells the XAML parser that the string needs to be parsed rather than being used as the name of a XAML namespace.

If the namespace is in another assembly, the process is similar, but you must also include the assembly name—without the .dll extension.

xmlns:lib="clr-namespace:MyLib;assembly=MyAssembly"

Leave a comment

Your email address will not be published. Required fields are marked *