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
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
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)
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
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}
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}
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
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