Click here to Skip to main content
15,867,750 members
Articles / Desktop Programming / WPF

Custom Value Conversion in WPF

Rate me:
Please Sign up or sign in to vote.
3.00/5 (14 votes)
24 Apr 2013CPOL2 min read 54.1K   730   11   8
This article describes how to perform custom value conversions in WPF.

Image 1

Introduction

In WPF, custom value converters can be used to convert data from one type to another. A custom converter can be used to implement custom logic to convert one value to another. To demonstrate this article, I have developed an application in Visual C# 2010 Express Edition, that takes a decimal value as input and converts it into binary, octal, and hexadecimal values.

Background

To create a custom converter, we need to implement the IValueConverter interface in our user-defined converter class. The IValueConverter interface has two methods which we must implement in our class. These methods are as follows:

  • Convert: This method converts a source value to target. This method's signature is as follows:
  • C#
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

    In this method we code the logic for our custom conversion.

  • ConvertBack: This method converts a value back from target to source. This method's signature is same as the Convert method. We can avoid writing custom code in this method if we do not want to convert a value back to source.

Using the Code

The following XAML code is used to define the user interface of our application:

XML
<Window x:Class="NumberSystemConversion.MainWindow"        
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:NumberSystemConversion"
        Background="BlanchedAlmond"
        Title="Number System Converter" Height="350" Width="600">
    <Window.Resources>
        <local:NumberSystemConverter x:Key="myConverter"/>
    </Window.Resources>
    <Canvas>
        <Label Canvas.Left="100" Canvas.Top="10" FontFamily="Comic Sans MS" 
               FontSize="32" Foreground="Fuchsia">Number System Converter</Label>
        <Label Canvas.Left="40" Canvas.Top="100" FontFamily="Aharoni" FontSize="24" 
               Foreground="BlueViolet">Enter a Decimal Number: </Label>
        <TextBox Name="txtDecimal" Canvas.Left="330" Canvas.Top="100" Width="225" 
               FontFamily="Aharoni" FontSize="24" 
               Foreground="BlueViolet" Background="LightPink"/>
        <Label Canvas.Left="220" Canvas.Top="150" FontFamily="Lucida Console" 
               FontSize="24" Foreground="Red">Binary:</Label>
        <TextBlock Name="txtBinary" Canvas.Left="330" Canvas.Top="150" Width="225" 
               FontFamily="Lucida Console" FontSize="24" Foreground="Red" Background="LightPink"
               Text="{Binding ElementName=txtDecimal,Path=Text,Converter={StaticResource myConverter},ConverterParameter=2}"/>
        <Label Canvas.Left="233" Canvas.Top="200" FontFamily="Lucida Console" 
               FontSize="24" Foreground="Green">Octal:</Label>
        <TextBlock Name="txtOctal" Canvas.Left="330" Canvas.Top="200" Width="225" 
               FontFamily="Lucida Console" FontSize="24" Foreground="Green" Background="LightPink"
               Text="{Binding ElementName=txtDecimal,Path=Text,Converter={StaticResource myConverter},ConverterParameter=8}"/>
        <Label Canvas.Left="147" Canvas.Top="250" FontFamily="Lucida Console" 
               FontSize="24" Foreground="Blue">Hexadecimal:</Label>
        <TextBlock Name="txtHexadecimal" Canvas.Left="330" Canvas.Top="250" Width="225" 
               FontFamily="Lucida Console" FontSize="24" Foreground="Blue" Background="LightPink"
               Text="{Binding ElementName=txtDecimal,Path=Text,Converter={StaticResource myConverter},ConverterParameter=16}"/>
    </Canvas>
</Window>

In the above code, I have created a window resource called myConverter which points to our custom converter class called NumberSystemConverter. A TextBox called txtDecimal is used to accept a number to be converted. Three TextBlocks: txtBinary, txtOctal, and txtHexadecimal are used to display the converted results. The three TextBlocks are bound to the txtDecimal TextBox using element binding. The converter NumberSystemConverter is used to convert the decimal number to binary, octal, and hexadecimal using the Converter property. The ConverterParameter property is used to specify the target type as 2, 8, and 16 for converting to binary, octal, and hexadecimal values, respectively.

Following is the code of our Number System Converter:

C#
public class NumberSystemConverter : IValueConverter
{
    Stack<object> stack = new Stack<object>();
    public object Convert(object value, Type targetType, object parameter, 
                  System.Globalization.CultureInfo culture)
    {
        // Store result digits in array
        object[] digits = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F" };
        try
        {
            // Get the source value
            int number = System.Convert.ToInt32(value.ToString());
            if (number == 0)
            {
                return 0;
            }
            // Get the target number system
            int divisor = System.Convert.ToInt32(parameter.ToString());
            while (number > 0)
            {
                int remainder = number % divisor;
                // Push digits to stack
                stack.Push(digits[remainder]);
                number /= divisor;
            }
            StringBuilder builder = new StringBuilder();
            while (stack.Count > 0)
            {
                builder.Append(stack.Pop().ToString());
                // Return digits in LIFO order
            }
            return builder.ToString();
            // Return result
        }
        catch (Exception)
        {
            return null;
        }
    }
    public object ConvertBack(object value, Type targetType, object parameter, 
                  System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

In the above code, the first parameter of the Convert method represents the number to be converted (number) and the third parameter represents the target number system (divisor). The number is divided by the divisor and the remainder is pushed into a stack. At the end, the numbers are popped out of the stack and appended to a StringBuilder object. The StringBuilder is converted to String and returned as the result to be displayed on the target TextBlock.

The ConvertBack method is not required to be implemented.

Points of Interest

Though there are many more uses of converters and a variety of ways of using converters, I hope that the above discussion would help in understanding the working of converters in WPF.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Instructor / Trainer NIIT, India
India India
I am a trainer by profession. Currently I am working with iFuture Technologies(India) as a Senior Faculty. I enjoy programming as a hobby. During my career I have seen the growth and decline of many technologies, many of them being my favorites like Flash, WPF, Windows Mobile Development. Few of my current favorites are Android, Xamarin and Python, though I also like traditional and evergreen languages like PHP, C#, Visual Basic and Java.

Apart from computers, my favorite pastime is bicycling.

Comments and Discussions

 
GeneralMy vote of 1 Pin
mungflesh21-Jan-15 3:33
mungflesh21-Jan-15 3:33 
GeneralMy vote of 1 Pin
KiwiPiet26-Aug-14 16:33
KiwiPiet26-Aug-14 16:33 
GeneralMy vote of 1 Pin
Yet Another XCoder24-Jun-13 6:25
Yet Another XCoder24-Jun-13 6:25 
GeneralMy vote of 1 Pin
zendu28-Apr-13 20:27
zendu28-Apr-13 20:27 
Question[My vote of 1] Another go no where article Pin
FatCatProgrammer25-Apr-13 5:24
FatCatProgrammer25-Apr-13 5:24 
AnswerRe: [My vote of 1] Another go no where article Pin
Azim Zahir25-Apr-13 16:03
Azim Zahir25-Apr-13 16:03 
GeneralMy vote of 1 Pin
Joe Sonderegger24-Apr-13 22:30
Joe Sonderegger24-Apr-13 22:30 
GeneralRe: My vote of 1 Pin
Azim Zahir25-Apr-13 6:18
Azim Zahir25-Apr-13 6:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.