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

Tagged as

WPF: Dictionary Value Converter

, 10 Aug 2011
Rate this:
Please Sign up or sign in to vote.
What’s the story? You want to convert an enum value to a bitmap image. That’s easy, here’s a solution Usually you would simply create a new value converter which has some custom code (e.g. a switch –case statement) to convert from the enum value to the relevant image. Is there a better solution

What’s the story?

You want to convert an enum value to a bitmap image.

That’s easy, here’s a solution

Usually you would simply create a new value converter which has some custom code (e.g. a switch –case statement) to convert from the enum value to the relevant image.

Is there a better solution?

How many times have you written this kind of converter, the kind that takes a value and maps it to another value?

Well, no more!

I present to you: DictionaryValueConverter. A Converter that lets you define a collection of key-value pairs and do the mapping for you.

So, how can I use this converter?

The following code provides a common usage of this converter. Here I map three enum values to three different bitmap images. Each value in the Values property is another image which is mapped by its x:Key.

<converters:DictionaryValueConverter x:Key="propertyTypeToImage">

    <converters:DictionaryValueConverter.Values>

        <BitmapImage x:Key="{x:Static local:PropertyType.Name}"

                     UriSource="Name.png" />

        <BitmapImage x:Key="{x:Static local:PropertyType.Age}"

                     UriSource="Age.png" />

        <BitmapImage x:Key="{x:Static local:PropertyType.Phone}"

                     UriSource="Phone.png" />

    </converters:DictionaryValueConverter.Values>

</converters:DictionaryValueConverter>

This is SO COOL, can I use it also to convert Booleans to Visibility?

Well, yes and no.

Theoretically, it will work. There is nothing in the code which prevents it.

Practically, you need a way to specify the “true” and “false” Boolean values as the keys.

Unfortunately, XAML 2006 doesn’t allow x:Key to have complex values (using property element syntax). This was fixed in XAML 2009, but WPF doesn’t support it yet.

To work around it you can define constants for the “true” and “false” values and use x:Static markup extension to provide the keys.

For example:

public static class BooleanValues
 {
     public const bool True = true;
     public const bool False = false;
 }
<converters:DictionaryValueConverter x:Key="booleanToVisibilityConverter">

    <converters:DictionaryValueConverter.Values>

        <Visibility x:Key="{x:Static local:BooleanValues.True}">Visible</Visibility>

        <Visibility x:Key="{x:Static local:BooleanValues.False}">Collapsed</Visibility>

    </converters:DictionaryValueConverter.Values>

</converters:DictionaryValueConverter>

So, how is it implemented?

Like this:

using System;
 using System.Collections.Generic;
 using System.Globalization;
 using System.Linq;
 using System.Windows;
 using System.Windows.Data;
 
 namespace Common.Converters
 {
     public class DictionaryValueConverter : IValueConverter
     {
         /// <span class="code-SummaryComment"><summary>
</span>         /// Store the key type.
         /// Setting this property is needed if your key is an enum and  
         /// <span class="code-SummaryComment"></summary>
</span>         public Type KeyType { get; set; }
 
         /// <span class="code-SummaryComment"><summary>
</span>         /// Store the key-value pairs for the conversion
         /// <span class="code-SummaryComment"></summary>
</span>         public Dictionary<object, object> Values { get; set; }
 
         public DictionaryValueConverter()
         {
             Values = new Dictionary<object, object>();
         }
 
         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
         {
             // if key type is not set, get it from the first dictionary value, usually it's the same for all the keys
             if (KeyType == null)
             {
                 KeyType = Values.Keys.First().GetType();
             }
 
             // if key type is an enum
             if (KeyType.IsEnum)
             {
                 // convert integral value to enum value
                 value = Enum.ToObject(KeyType, value);
             }
 
             // if dictionary contains the requested key
             if (Values.ContainsKey(value))
             {
                 // return the relevant value
                 return Values[value];
             }
 
             // otherwise, don't return a value, this will fall back to the binding FallbackValue
             return DependencyProperty.UnsetValue;
         }
 
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         {
             // no support for converting back
             return DependencyProperty.UnsetValue;
         }
     }
 }

You can download a demo application here.

That’s it for now, Arik Poznanski.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

Arik Poznanski
Software Developer (Senior) Verint
Israel Israel
Arik Poznanski is a senior software developer at Verint. He completed two B.Sc. degrees in Mathematics & Computer Science, summa cum laude, from the Technion in Israel.
 
Arik has extensive knowledge and experience in many Microsoft technologies, including .NET with C#, WPF, Silverlight, WinForms, Interop, COM/ATL programming, C++ Win32 programming and reverse engineering (assembly, IL).
Follow on   Twitter   Google+

Comments and Discussions

 
QuestionSeems like a rehash of... PinmemberSledgeHammer0111-Aug-11 5:01 

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.140821.2 | Last Updated 10 Aug 2011
Article Copyright 2011 by Arik Poznanski
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid