XAML binding to Enum

Hello girls and boys! Today I faced with already solved in many ways Task – binding enum values to combobox. There are many articles on the web about it, this one is most beautiful I found with 10 minutes research. But all these techniques seems to me unintuitive a little, that’s just my vision, but I decided to take another way to solve my problem.

Here I will give simplest possible implementation, which ofc can be complicated with more features. First of all we’ll create our helper class for bindings(I made it in singletone pattern, but it’s optional). BindableBase here is a custom base class, which implements INotifyPropertyChanged interface:

    public class BindingHelper : BindableBase
    {
        private static BindingHelper _instance = null;
        private BindingHelper() { /* Here you can put some default registers */ }
        public static BindingHelper Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new BindingHelper();
                }
                return _instance;
            }
        }

        public Dictionary<String, Object> Enums { get; } = new Dictionary<string, object>();

        public bool RegisterEnum(Type enumType)
        {
            if (!enumType.IsEnum || Enums.ContainsKey(enumType.Name))
            {
                return false;
            }

            Enums.Add(enumType.Name, Enum.GetNames(enumType));
            OnPropertyChanged(nameof(Enums));
            return true;
        }
    }

Next somewhere in the code-behind we must register enum type with BindingHelper. In my case it could be BindingHelper constructor, but I prefer do it somewhere in code:

    BindingHelper.Instance.RegisterEnum(typeof(YourEnumType));

And last step is to bind our ComboBox:

    <ComboBox xmlns:local="clr-namespace:Namespace_Of_BindingHelper"
                ItemsSource="{Binding Source={x:Static local:BindingHelper.Instance}, Path=Enums[YourEnumType]}" />

Ofc xmlns you can implement within any parent element of combobox. And that’s all. Why I like this approach more than others? I think because here we become single entry point through BindingHelper, it’s more intuitive and easily to understand what is going on, and we can simply implement any processing logic of binded entities. Eg. you want some keys to be delivered with enum values, then you could just modify RegisterEnum method like this:

    public bool RegisterEnum(Type enumType)
    {
        if (!enumType.IsEnum || Enums.ContainsKey(enumType.Name))
        {
            return false;
        }

        List<Tuple<Enum, String>> tuples = new List<Tuple<Enum, string>>();
        foreach (Enum e in Enum.GetValues(enumType))
        {
            tuples.Add(new Tuple<Enum, string>(e, e.ToString()));
        }
        Enums.Add(enumType.Name, tuples);
        OnPropertyChanged(nameof(Enums));
        return true;
    }

And XAML:

    <ComboBox xmlns:local="clr-namespace:Namespace_Of_BindingHelper"
                SelectedValuePath="Item1" DisplayMemberPath="Item2"
                ItemsSource="{Binding Source={x:Static local:BindingHelper.Instance}, Path=Enums[YourEnumType]}"
                SelectedValue="{Binding YourEnumType_Variable, Mode=TwoWay}" />

Ofc such approach can be handled not only to enums, but to any other data. I hope this will help someone in the future.

Advertisements