Click here to Skip to main content
15,847,583 members
Articles / Desktop Programming / WPF
Tip/Trick

Enum to ComboBox binding

Rate me:
Please Sign up or sign in to vote.
4.90/5 (20 votes)
7 May 2013CPOL1 min read 112.3K   2.9K   20   24
This tip gives a simple way to bind enum values into a ComboBox that could be reused in different applications.

Introduction

Any real world application would like to bind Enum values to a ComboBox. So it is always better to have a common code that will do the logic.

Using the Code

I have a helper class which exposes a property to get the enum type so that I can resolve the enum values.

C#
public static Type GetEnum(DependencyObject obj)
{
    return (Type)obj.GetValue(EnumProperty);
}
public static void SetEnum(DependencyObject obj, string value)
{
    obj.SetValue(EnumProperty, value);
}
// Using a DependencyProperty as the backing store for Enum.  
// This enables animation, styling, binding, etc...
public static readonly DependencyProperty EnumProperty =
    DependencyProperty.RegisterAttached("Enum", typeof(Type), 
    typeof(EnumHelper), new PropertyMetadata(null, OnEnumChanged));  

Get the values of the enum and set it as ComboBox ItemsSource.

C#
private static void OnEnumChanged(DependencyObject sender, 
                          DependencyPropertyChangedEventArgs e)
{
    var control = sender as ItemsControl;
    if (control != null)
    {
        if (e.NewValue != null)
        {
            var _enum = Enum.GetValues(e.NewValue as Type);
            control.ItemsSource = _enum;
        }
    }
}

Now the ComboBox will bind to the enum values, if we set the enum value in XAML.

C#
public enum Designation
{
   SoftwareEngineer,
   TeamLead,
   ProductManager
} 
HTML
<ComboBox x:Name="Designation" Margin="5" Grid.Row="5"
      SelectedItem="{Binding Designation, Mode=TwoWay}"
      local:EnumHelper.Enum="{x:Type local:Designation}">
</ComboBox>   

Image 1

Look at the names of items. They are not well spaced. It should be Product Manager instead of ProductManager. For this, we will use the Display attribute of enum values. Further, we can also use the Description attribute to let the user see more details.

I have modified my enum to look like below:

C#
public enum Designation
{
    [Display(Name="Software Engineer")]
    [Description("Software engineer responsible for core development.")]
    SoftwareEngineer,
    [Display(Name = "Team Lead")]
    [Description("Team lead responsible for leading a small team of 5 to 10 members.")]
    TeamLead,
    [Display(Name = "Product Manager")]
    [Description("Product manager responsible for core management.")]
    ProductManager
}  

Also our helper class should expose another property to get the values of attributes and set it wherever needed. For example, in this case I will show the description as a tooltip and display as text.

C#
public static bool GetMoreDetails(DependencyObject obj)
{
    return (bool)obj.GetValue(MoreDetailsProperty);
}
public static void SetMoreDetails(DependencyObject obj, bool value)
{
    obj.SetValue(MoreDetailsProperty, value);
}
// Using a DependencyProperty as the backing store for MoreDetails.  
// This enables animation, styling, binding, etc...
public static readonly DependencyProperty MoreDetailsProperty =
    DependencyProperty.RegisterAttached("MoreDetails", 
    typeof(bool), typeof(EnumHelper), new PropertyMetadata(false, OnMoreDetailsChanged)); 

We are getting the attribute values and set it in the appropriate places. We expect the user to set this property in any DataTemplate so that we can get the underlying enum object as a DataContext.

C#
var array = fieldInfo.GetCustomAttributes(false);
if (array.Length == 0)
{
    if (control is TextBlock)
    {
        ((TextBlock)control).Text = enumobject.ToString();
    }
    else if (control is ContentControl)
    {
        ((ContentControl)control).Content = enumobject;
    }
    return;
}
foreach (var o in array)
{
    if (o is DescriptionAttribute)
    {
        control.ToolTip = ((DescriptionAttribute) o).Description;
    }
    else if (o is DisplayAttribute)
    {
        if (control is TextBlock)
        {
            ((TextBlock) control).Text = ((DisplayAttribute) o).Name;
        }
        else if (control is ContentControl)
        {
            ((ContentControl)control).Content = ((DisplayAttribute)o).Name;
        }
    }
}  

Let's add a DataTemplate to the ComboBox:

XML
<DataTemplate>
    <TextBlock local:EnumHelper.MoreDetails="True"/>
</DataTemplate>   

Image 2

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India
Jawahar working as a Senior Development Engineer in Aditi Technologies,Bangalore, India. Specialist in all XAML frameworks. Very passionate on UX Design and Development. Skilled in Expression Blend, Design, WPF, Silverlight, Windows Phone 7/8, Windows 8. Good knowledge in Entity Framework, SQLite and SQL Server also. Also had good experience with PRISM, MVVM, Caliiburn Micro and other design patterns.

He developed few products for Syncfusion Inc. Also working on some freelancing projects. Worked as a lead developer of Metro Studio from Syncfusion Inc.

An active freelancer. http://xamlfactory.elance.com

http://about.me/jawahars

http://wpfplayground.com/

Comments and Discussions

 
QuestionNeat idea Pin
Kenneth Haugland18-Jun-15 12:40
mvaKenneth Haugland18-Jun-15 12:40 
QuestionSimilar method Pin
drussilla27-Jan-15 5:07
drussilla27-Jan-15 5:07 
I am using simpler (but not so powerfull) method.
Just add ObjectDataProvider
<ObjectDataProvider x:Key="enumValues"
       MethodName="GetValues" ObjectType="{x:Type System:Enum}">
          <ObjectDataProvider.MethodParameters>
               <x:Type TypeName="local:ExampleEnum"/>
          </ObjectDataProvider.MethodParameters>
     </ObjectDataProvider>

And then use binding to static resource:
<ComboBox ItemsSource="{Binding Source={StaticResource enumValues}}" />

here is full example: http://druss.info/2015/01/wpf-binding-itemssource-to-enum/
GeneralMy vote of 1 Pin
Member 988567418-Jan-15 22:52
Member 988567418-Jan-15 22:52 
GeneralMy vote of 1 Pin
Jalal Khordadi10-Dec-14 4:21
Jalal Khordadi10-Dec-14 4:21 
Bugbox doesn't refresh value Pin
negstek22-Oct-14 0:18
negstek22-Oct-14 0:18 
GeneralRe: box doesn't refresh value Pin
negstek22-Oct-14 23:45
negstek22-Oct-14 23:45 
GeneralMy vote of 1 Pin
Member 103920786-Oct-14 1:26
Member 103920786-Oct-14 1:26 
GeneralRe: My vote of 1 Pin
caronjudith7-Oct-14 5:44
caronjudith7-Oct-14 5:44 
Questionnice helper Pin
negstek25-Sep-14 3:16
negstek25-Sep-14 3:16 
GeneralMy vote of 1 Pin
Member 104580688-Aug-14 6:54
Member 104580688-Aug-14 6:54 
GeneralRe: My vote of 1 Pin
negstek25-Sep-14 3:34
negstek25-Sep-14 3:34 
QuestionBug Pin
m23tran15-Apr-14 12:23
m23tran15-Apr-14 12:23 
SuggestionRe: Bug Pin
FormatException11-Jul-14 5:57
FormatException11-Jul-14 5:57 
GeneralMy vote of 5 Pin
Andrey Moskvichev27-Nov-13 5:41
professionalAndrey Moskvichev27-Nov-13 5:41 
QuestionProblem Pin
Xoroles23-Sep-13 4:00
Xoroles23-Sep-13 4:00 
AnswerRe: Problem Pin
Member 99273029-Jan-14 5:50
Member 99273029-Jan-14 5:50 
GeneralRe: Problem Pin
Andreas Wittberg9-Apr-14 5:58
Andreas Wittberg9-Apr-14 5:58 
QuestionI'm getting an error Pin
Shane Montgomery20-Aug-13 13:03
Shane Montgomery20-Aug-13 13:03 
AnswerRe: I'm getting an error Pin
themightylechuck1-Sep-13 19:09
themightylechuck1-Sep-13 19:09 
GeneralRe: I'm getting an error Pin
Shane Montgomery2-Sep-13 5:26
Shane Montgomery2-Sep-13 5:26 
GeneralMy vote of 5 Pin
Gary M. Armstrong6-Aug-13 5:17
Gary M. Armstrong6-Aug-13 5:17 
QuestionRocks! Pin
Gary M. Armstrong6-Aug-13 5:17
Gary M. Armstrong6-Aug-13 5:17 
GeneralMy vote of 5 Pin
christoph brändle15-May-13 4:54
christoph brändle15-May-13 4:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.