WPF ComboBox and C# Enum – The Love Story

December 11, 2007

5 comments

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


I bet that you Googled this question more than once. Did you find the correct answer?


 


Well, I saw a lot of them, with code or XAML only, sorted, filtered, grouped, etc.


With all the respect, I didn’t get a generic answer with a two-way data-flow to a single enum-type property.


 


See these links as an example:


http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2430540&SiteID=1


http://joshsmithonwpf.wordpress.com/2007/06/20/displaying-sorted-enum-values-in-a-combobox/


http://www.codeproject.com/KB/WPF/FillComboboxWSortedEnum.aspx?print=true


http://blogs.msdn.com/wpfsdk/archive/2007/02/22/displaying-enum-values-using-data-binding.aspx


 


These are all great solutions for how to display a specific Enum value, but not to bind to a property of any-type of Enum (the type of the enum you want to bind to is not always known at design time, so you can’t use the specific type such as the AlignmentValues in the last link).


 


A: You can bind a property of type Enum (of any kind) to a ComboBox or ListBox controls by using a simple Value Converter and two Binding expressions as follows:


 

    public class EnumTypeConverter : IValueConverter
{
#region IValueConverter Members

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Enum.GetValues(value.GetType());
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}

#endregion
}


 

    <ComboBox ItemsSource=”{Binding Path=Sign, Converter={StaticResource enumConverter}}”
SelectedValue=”{Binding Path=Sign}” />

 


Download the code from here.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

5 comments

  1. עומר ון קלוטןDecember 12, 2007 ב 06:26

    Why was that last link not good again? It’s the classic way of doing that…
    Also, you don’t really have a two-way binding because your converter throws from convert-back (you should use Binding.DoNothing as a general rule).

    Reply
  2. Tomer ShamamDecember 12, 2007 ב 21:29

    1. The last link do not provide a way to bind to a property, only to display enum values and in other control (button), bind to the selected value. But it doesn’t provide solution to bind to a data-entity which has a CLR-property of an unknown enum type. Please look at the last link again, you will see that when using ObjectDataProvider you must provide a concrete type to create (in this case the XxxAlignment enum). My solution provides an option to bind to any CLR property with any type of enum which is unknown at design time, display the values in the combo-box, and update the CLR-property when the combo-box changes.

    2. If you do not permit a two-way/one-way-to-source binding by design, throw an exception as a general rule to eliminate surprises. As in a simple C# code, when you want to restrict an action at runtime, throw an exception.

    3. When I wrote “TwoWay” binding I meant one way to display enum values, the second to update the property.

    Reply
  3. עומר ון קלוטןDecember 13, 2007 ב 07:55

    1. So what you’re saying is “to hell with Type Safety!” 😀

    2. From MSDN[1]: “A return value of Binding.DoNothing indicates that the binding does not transfer the value […]”
    If it’s an errornous situation and isn’t a show-stopping one, you should just write a Trace message to stay consistent with the rest of WPF.

    [1] http://msdn2.microsoft.com/en-us/library/system.windows.data.ivalueconverter.convertback.aspx

    Reply
  4. Tomer ShamamDecember 13, 2007 ב 10:38

    1. I’m not dealing with types here, just provided a real generic solution for the problem. As for type-safety, XAML == “to hell with Type Safety!”, so I didn’t said that, the WPF team said that 🙂

    2. From MSDN[1]: “A return value of Binding.DoNothing indicates that the binding does not transfer the value […]” indeed, but from MSDN it is not written that “Do not throw an exception from a Value Converter, instead return value of Binding.DoNothing to indicate that the binding does not transfer the value”…, So did I missed something?

    Try to bind a readonly property with a default Two-Way binding property such as TextBox.Text and see what happens. So where is the consistency trace rule here?

    To stay friends, I will throw an exception (usually NotSupportedException with explanation), and you will return a Binding.DoNothing with a Trace 🙂

    By the way, why don’t you open an account at MyBlogLog, so I can see your face in my blog 😉

    Reply
  5. Rob BurkeFebruary 11, 2008 ב 20:33

    Nice tip. I agree with Tomer. This case comes up a lot and it’s much nicer to have just a single Converter for all my Enums that are going to be handled this way. I’m writing the XAML so I’m not worried about Type Safety here, just brevity of code.

    Reply