Hi All, I’m writing a post today about a common problem with MVVM and Enums. Sometimes you want a Selector control (ListBox, ComboBox) to bind to an Enum value in your ViewModel, with the Selector’s ItemsSource (selection options) being the collection of all possible Enum values – each with a descriptive selection text.
You can relatively easily hand-crank all of this with something like ValueConverters – with a different ValueConverter for each Enum type you use, and then for each Enum type used you would need one ValueConverter for the ItemsSource (convert Enum values to descriptive text), and one ValueConverter to convert the SelectedValue from the descriptive text back into the Enum value for your ViewModel – phew!
How about some code that will offer a re-useable solution for all of this – that is one set of code that can be used for all of your Enum bindings.
OK, First step – lets work out how we get a descriptive label for each of our Enum values wthin any Enum type.
One of the most popular ways to do this is to use the DescriptionAttribute on each of the Enum values, like this:
As you can see, above each Enum value, I have added a [Description] attribute, with the readable description of the Enum value below it. These descriptions will be what is seen in our Listbox or ComboBox later.
Now, in order to glue this all together, I have created a custom XAML behavior. This behavior can be added to the ListBox/ComboBox XAML declaration, and will take care of all the Bindings that need to happen between the Enum and the ViewModel.
You may notice that this custom Behavior has a helper class, called EnumContainer, and just a container for Enum values and their Description.
So, with the re-useable custom behavior class coded, implementing this solution on any place that it is required is going to be very easy indeed.
So, lets start with a simple sample app. First, the simple ViewModel that is required for MVVM.
This ViewModel has 2 main features of interest here. One is a Property of type CustomerType (our enum as described above) that has a getter and setter (for 2 way Binding), and also the ViewModel has an ICommand that we can use to Bind to a Button – so that we can change the CustomerType in the ViewModel and see that reflected in our ListBox via the Behaviors 2-way binding.
Below is that XAML, which may make it a little easier to understand:
And the code-behind to wire up the ViewModel
As you can see, the XAML and ViewModel are pretty simple. The only thing different is that we have the custom behavior declared inside the ListBox
And thats all it takes!
If you want a copy of the source code, it's available here in Git -