How to Bind an Enum to a ComboBox Control in UWP?

One of the ways to develop a desktop application for Windows 10/11 is UWP (Universal Windows Platform). UWP app has two fundamental sections, i.e. front-end and back-end. The front-end is developed using XAML (Extensible Markup Language) and back-end can be coded in C# (or even JavaScript back in the old time).

In order to decoupling front-end and back-end codes, there is a UI architectural design pattern, the MVVM (Model-View-ViewModel), introduced. With MVVM, we define our UI declaratively in XAML and use data binding markup to link it to other layers containing data and commands.

In order to implement MVVM in our UWP app, we can use Prism, which is an implementation of a collection of design patterns that are helpful in writing well-structured and maintainable XAML applications, including MVVM.

Even though Prism maintainers had decided to drop support for non-Xamarin.Forms UWP project back in 2019, Uno team announced that, in 2020, they stepped up to the plate and committed to providing ongoing support to the library.

In this article, we will figure out how we can setup data binding of an enum to a ComboBox control in UWP with Prism.

PROJECT GITHUB REPOSITORY

The complete source code of this project can be found at https://github.com/goh-chunlin/gcl-boilerplate.csharp/tree/master/universal-windows-platform/WTS.Prism.EnumCombo.

Model: The Enum

Let’s say we have an enum, MyColors, whose values are six different colours, as shown below.

public enum MyColors
{
    [Description("Red")] Red,
    [Description("Green")] Green,
    [Description("Blue")] Blue,
    [Description("Orange")] Orange,
    [Description("Pink")] Pink,
    [Description("Black")] Black
}

The enum has an attribute known as Description which can be retrieved with the extension method GetDescription().

public static class EnumExtension
{
    public static string GetDescription(this Enum value)
    {
        FieldInfo fi = value.GetType().GetField(value.ToString());
        var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
        if (attributes.Length > 0) return attributes[0].Description;
        else return value.ToString();
    }
}

ViewModel

Next we will define the ViewModel of our MainPage.xaml which will contains the ComboBox control. We will bind the variable SelectorColor whose type is the enum to the ComboBox control, as shown below.

public class MainViewModel : ViewModelBase
{
    private MyColors _selectedColor = MyColors.Black;

    public MyColors SelectedColor
    {
        get => _selectedColor;
        set
        {
            if (_selectedColor != value)
            {
                SetProperty(ref _selectedColor, value);
            }
        }
    }
}

The method SetProperty will set the property and notifies listeners only when necessary. The SetProperty method checks whether the backing field is different from the value being set. If different, the backing field is updated and the PropertyChanged event is raised.

Value Conversion

The data binding will be simple when the source and target properties are of the same type, or when one type can be converted to the other type through an implicit conversion, for example binding a string variable to the Text field of a TextBlock control. However, to bind enum to the dropdown value and text fields of a ComboBox, we will need the help of a value conversion.

The value conversion can be done by a converter class, which implements the IValueConverter interface. It will act like middlemen and translate a value between the source and the destination.

Here, we will implement a converter, MyColorValueConverter, that takes an enum value and then return a string value to be used in ComboBox fields, as well as the other way around.

public class MyColorValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value is MyColors color) return color.GetDescription();

        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        if (value is string s) return Enum.Parse(typeof(MyColors), s);
        
        return null;
    }

    ...

}

After this, in order to provide all available values in the enum as ItemsSource of the ComboBox control, we will need to have a Strings property in the MyColorValueConverter.

public string[] Strings => GetStrings();

public static string[] GetStrings()
{
    List<string> list = new List<string>();

    foreach (MyColors color in Enum.GetValues(typeof(MyColors)))
    {
        list.Add(color.GetDescription());
    }


    return list.ToArray();
}

View: The Front-end

Now in the MainPage.xaml which contains the ComboBox control, we first need to instantiate the value converter in the resource dictionary of the page.

<Page
    x:Class="WTS.Prism.EnumCombo.Views.MainPage"
    xmlns:local="using:WTS.Prism.EnumCombo.Helpers"
    ...>
    <Page.Resources>
        <local:MyColorValueConverter x:Key="MyColorValueConverter" />
    </Page.Resources>
    ...
</Page>

We then can have our ComboBox control defined as follows.

<ComboBox 
    ItemsSource="{Binding Source={StaticResource MyColorValueConverter}, Path=Strings}"
    SelectedItem="{Binding SelectedColor, Converter={StaticResource MyColorValueConverter}, Mode=TwoWay}"/>

Conclusion

That’s all for the quickstart steps to bind an enum to a ComboBox control in an UWP app.

I have made the source code available on GitHub. The code will have more features where the colour of text in a TextBlock will be based on the colour we pick from the ComboBox, as shown below.

Demo of the ComboBox on UWP.

References

One thought on “How to Bind an Enum to a ComboBox Control in UWP?

Leave a comment