Click here to Skip to main content
Click here to Skip to main content

Custom Value Conversion in WPF

By , 24 Apr 2013
Rate this:
Please Sign up or sign in to vote.

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:
  • 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:

<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:

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)

About the Author

Azim Zahir
Instructor / Trainer NIIT, India
India India
I am a trainer by profession. Currently I am working with NIIT (Mumbai, India) as a Senior Faculty. I enjoy programming as a hobby. My favorite technologies are Flash, Flex and Silverlight.
 
Of late I have developed keen interest in WPF and Windows Mobile programming.
 
Apart from computers, my favorite pastime is bicycling.

Comments and Discussions

 
GeneralMy vote of 1 Pinmemberrmiguel24-Jun-13 6:25 
Yet another MSDN copy...
GeneralMy vote of 1 Pinmemberzendu28-Apr-13 20:27 
Question[My vote of 1] Another go no where article PinmemberFatCatProgrammer25-Apr-13 5:24 
AnswerRe: [My vote of 1] Another go no where article PinmemberAzim Zahir25-Apr-13 16:03 
GeneralMy vote of 1 PinmemberJoe Sonderegger24-Apr-13 22:30 
GeneralRe: My vote of 1 PinmemberAzim Zahir25-Apr-13 6:18 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140415.2 | Last Updated 24 Apr 2013
Article Copyright 2012 by Azim Zahir
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid