Xamarin Forms Dictionary To Value Converter

Hi there!

Wanna map a set of keys to a set of values?

You do not want to create a specific converter for each use-case?

I find that normal. Do not let anyone tell you otherwise.


Introducing the brand new DictionaryToValueConverter:

public class DictionaryToValueConverter<T, U> : IValueConverter  
{
    public IDictionary<T, U> ValuesMapping { get; set; }

    public object Convert(object value, Type targetType, 
                          object parameter, CultureInfo culture)
    {
        if (ValuesMapping != null)
        {
            var keyT = (T)key;
            if (ValuesMapping.ContainsKey(keyT))
                return ValuesMapping[keyT];
            else
                return default(U);
        }
        else
            return default(U);
    }

    public object ConvertBack(object value, Type targetType, 
                              object parameter, CultureInfo culture)
    {
        throw new NotImplementedException(); // not relevant
    }
}

That converter will map a key to a value. For instance it could be a color for each enum value (we will get to that).


I did not implement the convert back as you could map several keys to the same value. It would not be relevant as you could find several keys for the same value. If you still want to you can use something like that:

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)  
{
    if (ValuesMapping != null)
    {
        var valueU = (U)value;
        var kvps = ValuesMapping.Where(kvp => kvp.Value.Equals(valueU));

        if (kvps.Any())
            return kvps.First().Key;
        else
            return default(T);
    }
    else
        return default(T);
}

But I would not approve that.


To declare this awesome converter you can follow the example right here:

var myEnumToColorConverter = new DictionaryToValueConverter<MyEnum, Color>()  
{
    ValuesMapping = new Dictionary<MyEnum, Color>
        {
            { MyEnum.Enum1, Color.Red },
            { MyEnum.Enum2, Color.Green },
            { MyEnum.Enum3, Color.Blue },
            { MyEnum.Enum4, Color.Yellow }
        }
};

And to use it:

myObject.SetBinding<ObservableObject>(MyObject.ColorProperty,  
                                      o => o.EnumValue, 
                                      converter: myEnumToColorConverter);

All done.

Of course you can also use:

SetBinding(MyObject.ColorProperty, new Binding("EnumValue", converter: myEnumToColorConverter))  

I am not a monster. Do whatever you want. Use XAML if you prefer.


Last-minute tips:

Do not declare a converter per view. Create a converter and use it for all your views.

Do not create too complex things. The simpler the better, if you are re-creating the earth each time you might want to create a specific converter.

In short words: be smart.


Paul, out!