Displaying Enum Values using Data Binding
Some of the FAQs about data binding are:
• How do I bind to a method?
• How do I bind between instantiated controls?
• How do I bind an ItemsControl to an enum?
I put together a quick sample that should answer the above questions:
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
SizeToContent="WidthAndHeight"
Title="Show Enums in a ListBox using Binding">
<Window.Resources>
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type sys:Enum}"
x:Key="AlignmentValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="HorizontalAlignment" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<Border Margin="10" BorderBrush="Aqua"
BorderThickness="3" Padding="8">
<StackPanel Width="300">
<TextBlock>Choose the HorizontalAlignment
value of the Button:</TextBlock>
<ListBox Name="myComboBox" SelectedIndex="0" Margin="8"
ItemsSource="{Binding Source={StaticResource
AlignmentValues}}"/>
<Button Content="Click Me!"
HorizontalAlignment="{Binding ElementName=myComboBox,
Path=SelectedItem}"/>
</StackPanel>
</Border>
</Window>
The ListBox and the Button are hooked up such that you can “control” the HorizontalAlignment value of the Button by selecting a value in the ListBox. This is a screenshot of the example:
So, the answers to the questions are:
• You bind to a method using the ObjectDataProvider. In the example above, we are binding to Enum.GetValues. Specifically, Enum.GetValues(typeof(HorizontalAlignment)).
• You bind the property of a control to a property of another control using the ElementName property of the Binding class. In the example above, the Button HorizontalAlignment property is bound to the SelectedItem property of the ComboBox.
• You bind to an enum by binding to the Enum.GetValues method.
Comments
Anonymous
December 11, 2007
Q: How can I bind a property of type Enum (of any kind) to a ComboBox or ListBox controls? I bet thatAnonymous
March 27, 2008
Thanks for the example. However, it doesn't really bind to a data field. It's a great example of how to get the list to show the enum values, but it doesn't associate the selected value with anything. Additionally, in real world apps nobody would do it this way. You would want a class to associate the enum values with some internationalizable text, not the actual name of the enum value. For example, if your enum value were MyEnum.Column1 you would want to see the user-friendly text "Column One" or at least "Column 1" with a space. And you'd want to be able to change that for other languages. Woulda been great if the framework could've provided an easy means to accomodate that considering how common enums are as a property value.Anonymous
May 27, 2009
A little late to this party but... You can get around all the shortcomings you mentioned with a ValueConverter. Simply bind to the Enum.GetValues method, and have your ValueConverter lookup the internationalized pretty print string for the enum, and return a ComboBoxItem with a DisplayProperty of the print string, and a ValueProperty of the enum.Anonymous
June 05, 2009
I find that using an ObjectDataProvider for doing that is too verbose... I use a custom markup extension instead : [MarkupExtensionReturnType(typeof(IEnumerable))] public class EnumValuesExtension : MarkupExtension { public EnumValuesExtension() { } public EnumValuesExtension(Type enumType) { this.EnumType = enumType; } [ConstructorArgument("enumType")] public Type EnumType { get; set; } public override object ProvideValue(IServiceProvider serviceProvider) { if (this.EnumType == null) throw new ArgumentException("The enum type is not set"); return Enum.GetValues(this.EnumType); } } It can be used like that : <ListBox Name="myComboBox" SelectedIndex="0" Margin="8" ItemsSource="{my:EnumValues HorizontalAlignment}"/>