Jun 04, 2006

How to bind an ItemsControl to the values of an enumeration

25BindToEnum

Today I will show how you can bind a ComboBox to all the possible values of an enumeration, using only XAML. This scenario was blocked by a bug in Feb CTP bits, so you will need Beta 2 bits to run this sample.

I have the following enumeration in the code behind of this sample:

    public enum TShirtSizes
    {
        Small,
        Medium,
        Large
    }

In the UI of my application, I have a ComboBox for TechEd staff to pick their T-Shirt size (you guys are all going to TechEd in Boston next week, right?). I want the entries in that ComboBox to display the values in the enum.

This is really easy to do. It turns out that there is a static method on Enum that returns an Array of all the values of a particular enumeration. This is how we could get the array of values through code:

    Enum.GetValues(typeof(TShirtSizes));

Binding to this method can easily be done in XAML by using ObjectDataProvider:

    <ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type sys:Enum}" x:Key="odp">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="local:TShirtSizes"/>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>

    <StackPanel>
        <Label>Select the size of your TechEd T-Shirt:</Label>
        <ComboBox ItemsSource="{Binding Source={StaticResource odp}}" IsSynchronizedWithCurrentItem="true"/>
    </StackPanel>

I explained binding to a method using ObjectDataProvider in an earlier post. As you can see, there is nothing special about using ObjectDataProvider to bind to a *static* method (with the exception of the bug in Feb CTP).

Keep in mind that the values of the enumeration will be displayed in the ComboBox in the order they are defined (though you can control their order by sorting them with the help of a CollectionViewSource).

Below is a screenshot of the application:

Here you can find the VS project with this sample code. This works with Beta2 WPF bits.

12 Comments
  1. Jonathan Merriweather

    Hey,

    I’m wanting to bind to System.Windows.Forms.SystemInformation.UserName.

    How can I bind to the .NET framework classes just like how I bind to my own classes?

    Cheers,

    Jon Merriweather

    • Jonathan Merriweather

      I figured it out.. you must use this as your namespace:

      xmlns:forms=”clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms”

      Cheers

      • Bea

        That’s correct :) You got it!
        Bea

  2. Sam

    I’ve got a binding problem I can’t think of any way to solve:

    I want to draw my own fancy border around a TextBox.
    Problem is, it can’t be scaled automagically like a rectangle could, I need to bind to the size of the textbox to use it as coordinates in a path.

    With a custom converter this does work nicely for ActualWidth or ActualHeight alone, but of course to get the bottom right corner I need to bind to ActualHeight and ActualWidth at once, and I can’t find no way to achieve this.

    Is there a way to bind to ActualWidth and ActualHeight at once? Or to create a converter that is bound to both and can itself be bound to?

    Or maybe there is a whole other way to get the size of a control in a template for userdrawn content that can be bound to?

    Thanks a lot!
    Sam

  3. Bea

    Hi Sam,

    I believe a MultiBinding would solve your problem. Basically, it allows you to bind to two sources at the same time. You will have to write a converter that takes both sources as a parameter and produces the final value you want to show in the target.

    I will keep this in mind for a future blog post. In the meantime, I’m pretty sure the SDK has samples with this. If it doesn’t I’ll make this my *next* blog post. Let me know.

    Bea

    • Sam

      Oh I love those keywords triggering a whole new load of information on google.
      Multibind was *the* magic word (names *are* power nowadays).

      Charles Petzold had an usable example for me how to do it, and it works lovely!

      Thanks a lot, I owe you one!

      • Bea

        I’m glad to hear that :)

  4. perter

    After looking at your enumeration binding example (June 4 2006 blog) I have implemented something similar in my app. However, language translation is an obvious issue going forward. Would you know of any good samples to outline how to do this properly for translation and secondly a good overview of globalization for WPF apps? I would love to see a sample implementation in simple terms rather than the MSDN docs. Thanks!

    • Bea

      Hi perter,

      Yes, I realize that this sample is quite limited when it comes to language translation. I have seen people implementing this scenario by adding attributes over each value in the enumeration with better descriptions of each value. This method is more realistic than the one in this post because it allows sentences to be displayed in the ComboBox, but I’m not sure how this would tie into globalization. You’re probably aware of the globalization docs in MSDN. Other than that, our WPF globalization expert, Chris Han, maintains a blog here. He’s incredibly smart and knowledgeable on this topic, and may be able to give you some pointers.

      Sorry if I can’t be more helpful on that topic,
      Bea

  5. Dave

    Hi Bea,

    Great article, I have an enumerator list that is bound to a combo box using the ObjectDataProvider works great, the problem is I need to be able to keep different elements of the enumerator from showing in the combo box based on other settings in the application. Using your example above; in most cases I want all three values but for this one instance I want just Small and Large (not medium) from the TShirtSizes enumeration (in short I need to keep the enumeration for the combo box because data is persisted to stream as an enumerated value). Any help would be appreciated.

    Thanks
    Dave G.

    • Dave

      Bea,

      I figured it out by using a CollectionViewSource and then filter method into a code routine that filters the enumerator. Still love your website and visit as often as I can.

      Dave G.

      • Bea

        I’m glad you were able to figure it out!

        Bea

Comments are closed.