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=http://schemas.microsoft.com/winfx/2006/xaml/presentation


  xmlns:x=http://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 (4)

  1. Q: How can I bind a property of type Enum (of any kind) to a ComboBox or ListBox controls? I bet that

  2. jrichview says:

    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.

  3. KellenF says:

    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.

  4. Thomas Levesque says:

    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}"/>