Hi all

As you all remember in my article about Custom WPF Context Menu I mentioned that my WPF Binding Converter was a singleton, and I promised to tell you why, so here comes the 3 ways I know of using WPF Binding Converters. We will start from the worst (in my opinion) and move on the the best.

To start off here is the Binding Converter:

1: public class IntConverter : IValueConverter
2: {
3:    #region IValueConverter Members
4: 
5:    public object Convert(object value,
6:                          Type targetType,
7:                          object parameter,
8:                          System.Globalization.CultureInfo culture)
9:    {
10:       if (value is int)
11:       {
12:         int a = (int)value;
13:         switch (a)
14:         {
15:             case 1:
16:               return "One";
17:             case 2:
18:               return "Two";
19:             case 3:
20:               return "Three";
21:             default:
22:               return "Bigger than Three";
23:             break;
24:         }
25:      }
26:      return "Error";
27:   }
28: 
29:   public object ConvertBack(object value,
30:                             Type targetType,
31:                             object parameter,
32:                             System.Globalization.CultureInfo culture)
33:   {
34:      return null;
35:   }
36: 
37:   #endregion
38: }

Pretty simple.

The Static Resource Way

This is the most simple way of using WPF converters, create you Converter Class and link to it as a StaticResource. Here is the code:

1: <Window.Resources>
2:    <conv:IntConverter x:Key="IntConverter"></conv:IntConverter>
3: </Window.Resources>
4: <StackPanel>
5:    <TextBlock x:Name="Result" Margin="15" FontSize="20"
6:               HorizontalAlignment="Center" VerticalAlignment="Center"
7:               Text="{Binding Converter={StaticResource IntConverter}}">
8:    </TextBlock>
9: </StackPanel>
10:</Window>

This is very easy and simple but there is one drawback to it which I hope the WPF team will fix someday. It appears that every time there is a need to use the converter the Application will create a new Converter class, use it and then dispose it. If you have a heavy application with allot of binding and converters this could be costly. I am not 100% sure that it is true but I did allot of checking and the performance is slower. So lets move on to the next way.

The Static Converters Class

Here we will not allow WPF to create and dispose the Converters all the time be creating a Static Class that will hold all the Converters in one place something like this:

1: public static class ConvertersHolder
2: {
3:    public static readonly IntConverter m_IntConverter = new IntConverter();
4: }

You can add as may converters as you want to this class. It is sort of a Converters repository. Here is the code for using the converter:

1: <StackPanel>
2:
<TextBlock x:Name="Result" Margin="15" FontSize="20" HorizontalAlignment="Center"
3:            VerticalAlignment="Center"
4:       Text="{Binding Converter={x:Static conv:ConvertersHolder.m_IntConverter}}">
5: </TextBlock>
6: </StackPanel>

Ok, lets take a break.

The first example is simple but costly. the second one is better in performance but requires maintaining a Converters class. If only we could get rid of maintaining the Converters Class… We Can!!!

The Singleton Converter Class

This method will allow us to enjoy both worlds. First we will need to add a singleton implementation to the Converter ( I know it is not thread safe and all…):

1: #region Singleton Implementation
2:
 
3: private static IntConverter instance = new IntConverter();
4: 
5: private IntConverter()
6: {
7: }
8: 
9:  /// <summary>
10: /// The converter instance
11: /// </summary>
12: public static IntConverter Instance
13: {
14:   get
15:   {
16:      return instance;
17:   }
18: }
19: 
20: #endregion

And the Usage is similar to the second example:

1: <StackPanel>
2:
   <TextBlock x:Name="Result" Margin="15" FontSize="20"
3:            HorizontalAlignment="Center"
4:            VerticalAlignment="Center"
5:          Text="{Binding Converter={x:Static conv:IntConverter.Instance}}">
6:   </TextBlock>
7: </StackPanel>

No you don’t have to maintain a converter class. I think this is the best method for using Converters. I made myself a template for a converter that already has the singleton implementation so creating a new one is easy.

Subscribe to our feed and get the complete code sample for this article.

Don’t forget to check out the Context Menu article where it all started :)

Need help or know of a different way of using Converters? Let me know

Amit.

Tags :

20 Responses to “WPF Binding Converter Best Practices”


  1. contrapunctus

    Said on July 18, 2008 :

    very nice! thanks for this idea.

  2. The Reddest

    Said on July 20, 2008 :

    We’ve tested it, and the converter is not created and destroyed every time it’s used. If it where, you would not be able to persist any information between convert calls, which would not be good. Regardless of how many times the the converter is referenced in xaml or how many times the converter is used, it is only instantiated once when it is added to your resources collection.

  3. Amit

    Said on July 21, 2008 :

    @ Reddest

    Really?

    How did you test it? My tests showed different results. Maybe I should conduct them again, they were a long time ago…

    Amit

  4. The Reddest

    Said on July 21, 2008 :

    We did a simple Console.WriteLine() in the converter’s constructor. We then tested persistence by updating a member variable every time convert was called. Both indicated the object was created once. I’d be curious to how you tested it.

  5. Amit

    Said on July 22, 2008 :

    I must say I did the something very much alike.
    I will have to test it again, thanks!

    Will get back once tested.

    Amit

  6. contrapunctus

    Said on September 22, 2008 :

    hi Amit, did you do the new test you were talking about?

    thanks.

  7. Amit

    Said on September 25, 2008 :

    Thanks for the reminder

    I acctually forgot about it :(

    I will try and get to it this weekend

    Amit

  8. Gopalakrishnan

    Said on January 19, 2010 :

    I would like to create miniToolbar like office 2007 in WPF.
    Whether do i need to create from scrash or is it possible in RibbonControlsLibrary from microsoft. Please let me know any suggestion. It would be best if you have sample

    Gopal

  9. Bishoy Harby

    Said on February 24, 2010 :

    thank you for the article , i have a newbie question though , in the window.resources tag , i’ve tried but the visual studio was giving me error.

  10. Bishoy

    Said on February 24, 2010 :

    Sorry , my fault , got the namespace thing :D xmlns:conv , thank you again for the great article

  11. Valentine

    Said on October 23, 2010 :

    Hi, I have a trouble with converters.

    I have a treeview with multibinding. it needs to use a converter.

    my classes:

    public class Company: INotifyPropertyChanged{

    public Company ParentCompany {get; set;}
    public string Title {get; set;}
    public Company ChildCompanies {get; set;}
    public Project Projects {get; set;}
    ….
    }

    public class Project: INotifyPropertyChanged{

    public string Title {get; set;}
    public int Price {get; set;}
    public Company ParentCompany {het; set;}

    }

    and a simple treeview:

    sorry, my english is not very good :)

  12. Adnan

    Said on January 23, 2011 :

    Nice & Easy!

  13. Saurabh

    Said on March 31, 2011 :

    Hi Amit,

    Thanks for this article but I understand that converter is not created many times. If you check hashcode of the converter object then it is always same for a continuous run.

    —————————————

    case 1:
    return “One” + this.GetHashCode();
    —————————————

    Please advise if you have checked it by any other mean.

  14. Snehanshu

    Said on April 13, 2012 :

    Hey Amit,
    This is an interesing post. Even though the converter is created only once per resources definition, a singleton converter will definitely add value when the converter is used across multiple forms.
    I have explained that in this small post:
    http://shulearnstowpf.blogspot.com/2012/04/singleton-value-converters-in-wpf.html

  15. Dennis Hayes

    Said on June 1, 2012 :

    I created a constructor for a converter and put a break point in it. The break point was hit only once, so I assume the converter is only created once. This was with the 4.0 framework, maybe earlier frameworks behaved differently.
    Dennis

5 Trackback(s)

  1. Jul 18, 2008: Arjan`s World » LINKBLOG for July 18, 2008
  2. Jul 29, 2008: WPF Binding Converter Best Practices « Rams On It - .NET
  3. Sep 26, 2008: WPF BINDING CONVERTER BEST PRACTICES CONTINUED | Dev102.com
  4. Jan 10, 2009: Bookmarks about Converters
  5. Apr 28, 2013: .NET 4 WPF Binding Converters: Best practices | Joan Comas Fdz

Post a Comment