-
Silverlight 4 ComboBox databinding to an Enum
Posted on April 8th, 2010 2 commentsAs you probably know, databinding to an enum in WPF is terribly easy with a few simple lines of XAML code like so:
<ObjectDataProvider x:Key="ZoomOptions" MethodName="GetNames" ObjectType="{x:Type sys:Enum}" > <ObjectDataProvider.MethodParameters> <x:Type TypeName="bll:enumZoomOptions"/> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> <ComboBox ItemsSource="{Binding Source={StaticResource ZoomOptions}}" />And that’s it… the ComboBox has a nice pretty list of all your enum’s values.
But in Silverlight 4, not only is the Enum.GetNames method unavailable, the ObjectDataProvider XAML syntax used above also is a stretch. So here’s how I got by…
First off, to lay a few things out, the nice thing about the WPF implementation above is that when we add a new value to the enumeration named ‘enumZoomOptions’, we simply add it and don’t have to go change our XAML (or any other code). I wanted to make sure I kept this flexibility. Also, my example code is structured around the MVVM framework but I’d do it the exact same way if code-behind was in play.
So let’s get started, first, I create my enumeration:
public enum ZoomOption : int { Fifty = 50, SeventyFive = 75, OneHundred = 100 }Now I set up my properties on my ViewModel to store the enum data:
private ObservableCollection _zoomOptions; public ObservableCollection ZoomOptions { get { return _zoomOptions; } set { _zoomOptions = value; RaisePropertyChanged("ZoomOptions"); } } private ZoomOption _selectedZoomOption = ZoomOption.OneHundred; public ZoomOption SelectedZoomOption { get { return _selectedZoomOption; } set { _selectedZoomOption = value; RaisePropertyChanged("SelectedZoomOption"); } }One note here is the SelectedZoomOption property is not really needed for this specific example except for setting the SelectedItem property so I can default the selected value in the databound ComboBox to 100.
Now the fun part, I need to populate my ZoomOptions collection with the values from my enumeration. In my ViewModel constructor, I do this:
// Get the type Type enumType = typeof(ZoomOption); // Set up a new collection ZoomOptions = new ObservableCollection(); // Retrieve the info for the type (it'd be nice to use Enum.GetNames here but alas, we're stuck with this) FieldInfo[] infos; infos = enumType.GetFields(BindingFlags.Public | BindingFlags.Static); // Add each proper enum value to the collection foreach (FieldInfo fi in infos) { ZoomOptions.Add((ZoomOption)Enum.Parse(enumType, fi.Name, true)); }So this effectively iterates through the enumeration value and adds each one to the collection.
Now the easy part… I simply bind my ComboBox to the collection of enum values and voila, it’s populated.
<ComboBox Grid.Row="1" Width="100" x:Name="ZoomComboBox" Height="25" ItemsSource="{Binding ZoomOptions}" />
The problem now though is it really isn’t displayed like I want it so simply override the datatemplate and use a converter to show the numerical value with the ‘%’ character afterwards. So I make it a little more user friendly by overriding the DataTemplate and providing a converter to show the actual value of the enum followed by the ‘%’ character.
Here’s the converter:
public class ZoomOptionDisplayConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { // This converts out enum values to a more acceptable display text if (value != null) { return System.Convert.ToInt32(value).ToString() + "%"; } else return null; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } }Here’s the new XAML for the ComboBox:
<UserControl.Resources> <local:ZoomOptionDisplayConverter x:Key="ZoomOptionDisplayConverter" /> </UserControl.Resources> <ComboBox Grid.Row="1" Width="100" x:Name="ZoomComboBox" Height="25" ItemsSource="{Binding ZoomOptions}" SelectedItem="{Binding SelectedZoomOption, Mode=TwoWay}" > <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Converter={StaticResource ZoomOptionDisplayConverter}}" /> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox>And our final result:

So I posted up an example project you can download here. In this example project, I go a few steps farther and actually use the enumeration value selected in the combobox for a realistic use case (I hate examples that you’d never use in the real world). So upon selection in the combobox, the text above it will both show the selected value as well as change the scale to the selected value… effectively performing a “zoom”.
You can try it out here:
2 responses to “Silverlight 4 ComboBox databinding to an Enum”

-
Thanks for this usefull post… I’ve translated it to VB.Net and made it generic so you can use it with every Enum you need. Maybe later I’ll write a post on my blog with that.
-
Ashish Tank June 28th, 2011 at 05:02
Nice One
Leave a reply
-


Jean Paul Mir February 21st, 2011 at 09:18