WPF
databinding
ComboBox
enum
C#

Databinding an enum property to a ComboBox in WPF

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Binding an enum to a ComboBox in WPF lets users select from a fixed set of options without hardcoding strings in XAML. The standard approach uses Enum.GetValues() to populate the ComboBox items and two-way data binding to sync the selected value with a view model property. For display-friendly names (e.g., "Dark Blue" instead of DarkBlue), you can use DescriptionAttribute with a custom converter or an ObjectDataProvider in XAML.

Define the Enum and ViewModel

csharp
1// Enum definition
2public enum ColorOption
3{
4    Red,
5    Green,
6    Blue,
7    DarkBlue,
8    LightGreen
9}
10
11// ViewModel with INotifyPropertyChanged
12using System.ComponentModel;
13
14public class SettingsViewModel : INotifyPropertyChanged
15{
16    private ColorOption _selectedColor = ColorOption.Blue;
17
18    public ColorOption SelectedColor
19    {
20        get => _selectedColor;
21        set
22        {
23            if (_selectedColor != value)
24            {
25                _selectedColor = value;
26                OnPropertyChanged(nameof(SelectedColor));
27            }
28        }
29    }
30
31    // Expose all enum values as a property
32    public Array ColorOptions => Enum.GetValues(typeof(ColorOption));
33
34    public event PropertyChangedEventHandler PropertyChanged;
35
36    protected void OnPropertyChanged(string propertyName)
37    {
38        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
39    }
40}

The view model exposes both the selected value and the list of all enum values. Enum.GetValues() returns all members of the enum type as an array.

Bind in XAML

xml
1<Window x:Class="MyApp.MainWindow"
2        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4        Title="Enum Binding Demo" Height="200" Width="300">
5    <Window.DataContext>
6        <local:SettingsViewModel />
7    </Window.DataContext>
8
9    <StackPanel Margin="20">
10        <TextBlock Text="Select Color:" Margin="0,0,0,5" />
11        <ComboBox ItemsSource="{Binding ColorOptions}"
12                  SelectedItem="{Binding SelectedColor}" />
13        <TextBlock Text="{Binding SelectedColor, StringFormat='Selected: {0}'}"
14                   Margin="0,10,0,0" />
15    </StackPanel>
16</Window>

ItemsSource binds to the array of enum values. SelectedItem uses two-way binding by default for ComboBox, so selecting an item updates the view model property.

Using ObjectDataProvider (No ViewModel Property Needed)

xml
1<Window x:Class="MyApp.MainWindow"
2        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4        xmlns:sys="clr-namespace:System;assembly=mscorlib"
5        xmlns:local="clr-namespace:MyApp">
6
7    <Window.Resources>
8        <ObjectDataProvider x:Key="ColorValues"
9                            MethodName="GetValues"
10                            ObjectType="{x:Type sys:Enum}">
11            <ObjectDataProvider.MethodParameters>
12                <x:Type TypeName="local:ColorOption" />
13            </ObjectDataProvider.MethodParameters>
14        </ObjectDataProvider>
15    </Window.Resources>
16
17    <ComboBox ItemsSource="{Binding Source={StaticResource ColorValues}}"
18              SelectedItem="{Binding SelectedColor}" />
19</Window>

ObjectDataProvider calls Enum.GetValues(typeof(ColorOption)) directly in XAML, so you do not need a ColorOptions property in the view model.

Display-Friendly Names with DescriptionAttribute

csharp
1using System.ComponentModel;
2
3public enum ColorOption
4{
5    [Description("Red")]
6    Red,
7    [Description("Green")]
8    Green,
9    [Description("Blue")]
10    Blue,
11    [Description("Dark Blue")]
12    DarkBlue,
13    [Description("Light Green")]
14    LightGreen
15}
16
17// Extension method to get the Description
18public static class EnumExtensions
19{
20    public static string GetDescription(this Enum value)
21    {
22        var field = value.GetType().GetField(value.ToString());
23        var attr = field?.GetCustomAttributes(typeof(DescriptionAttribute), false)
24                        .FirstOrDefault() as DescriptionAttribute;
25        return attr?.Description ?? value.ToString();
26    }
27}
csharp
1// Value converter for XAML binding
2using System.Globalization;
3using System.Windows.Data;
4
5public class EnumDescriptionConverter : IValueConverter
6{
7    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
8    {
9        if (value is Enum enumValue)
10            return enumValue.GetDescription();
11        return value?.ToString();
12    }
13
14    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
15    {
16        // Not needed for display — ComboBox SelectedItem handles the enum value
17        throw new NotImplementedException();
18    }
19}
xml
1<Window.Resources>
2    <local:EnumDescriptionConverter x:Key="EnumDescConverter" />
3</Window.Resources>
4
5<ComboBox ItemsSource="{Binding ColorOptions}"
6          SelectedItem="{Binding SelectedColor}">
7    <ComboBox.ItemTemplate>
8        <DataTemplate>
9            <TextBlock Text="{Binding Converter={StaticResource EnumDescConverter}}" />
10        </DataTemplate>
11    </ComboBox.ItemTemplate>
12</ComboBox>

The ItemTemplate with the converter displays "Dark Blue" to the user while the bound SelectedItem remains the DarkBlue enum value.

Excluding Enum Values

csharp
1// ViewModel property that filters out certain values
2public IEnumerable<ColorOption> AvailableColors =>
3    Enum.GetValues(typeof(ColorOption))
4        .Cast<ColorOption>()
5        .Where(c => c != ColorOption.DarkBlue);  // exclude DarkBlue
6
7// XAML
8// <ComboBox ItemsSource="{Binding AvailableColors}"
9//           SelectedItem="{Binding SelectedColor}" />

Common Pitfalls

  • ComboBox shows the enum member name (e.g., DarkBlue) instead of a friendly name: By default, WPF calls ToString() on enum values. Use DescriptionAttribute with an IValueConverter in an ItemTemplate to display human-readable names like "Dark Blue".
  • SelectedItem binding not updating the ViewModel: Ensure the ViewModel property type matches the enum type exactly. If the ComboBox ItemsSource contains object[] from Enum.GetValues() and the property is typed as the specific enum, the binding works. But if there is a type mismatch (e.g., binding to a string property), updates silently fail.
  • Forgetting INotifyPropertyChanged: Without raising PropertyChanged in the setter, the UI does not update when the property changes programmatically. The ComboBox selection appears to work (user changes propagate to ViewModel), but ViewModel-initiated changes do not reflect in the UI.
  • ObjectDataProvider namespace errors: ObjectDataProvider needs xmlns:sys="clr-namespace:System;assembly=mscorlib" for the Enum type. Missing this namespace causes a XAML compile error. In .NET Core / .NET 5+, use assembly=System.Runtime instead of mscorlib.
  • Enum values changing at runtime: Enums are compile-time constants. If you need a dynamic set of options, use a collection of objects with a display name and value property instead of an enum. Enums are only appropriate for fixed, known sets of values.

Summary

  • Expose Enum.GetValues(typeof(MyEnum)) as a ViewModel property or use ObjectDataProvider in XAML
  • Bind ItemsSource to the enum values and SelectedItem to the ViewModel property
  • Use DescriptionAttribute with an IValueConverter for user-friendly display names
  • Use ItemTemplate with a converter to show descriptions while binding to enum values
  • Implement INotifyPropertyChanged to keep the UI in sync with ViewModel changes
  • Filter enum values with LINQ in the ViewModel when certain options should be excluded

Course illustration
Course illustration

All Rights Reserved.