A lot of times in GUIs we use ComboBoxes to let the user choose one of several options. An enum property is a natural fit to store the selected value in the viewmodel via databinding.
To set the available values the MVVM way you typically have to databind the ItemsSource-Property to a collection. This means you have to code a collection somewhere, either in your viewmodel or in a static class. For Example:
class SomeViewModel
{
public ContactType[] PossibleContactTypes => new ContactType[] {
ContactType.Email,
ContactType.Sms,
ContactType.Phone
};
public ContactType SelectedContactType { get; set; }
}
And then use one way binding to set PossibleContactTypes as ItemsSource:
<ComboBox ItemsSource="{Binding PossibleContactTypes}"
SelectedItem="{Binding SelectedContactType}" />
If you have a lot of enum backed ComboBoxes this adds a lot of extra lines of code to your viewmodels.
But: If our goal is to display all values in the enum, we can create a collection containing all of them from just the enum type. Plus we can create a custom markup extension to get rid of the boilerplate code in our viewmodels. The markup extension looks like this:
public class EnumCollectionExtension : MarkupExtension
{
public Type EnumType { get; set; }
public override object ProvideValue(IServiceProvider _)
{
if(EnumType != null)
{
return CreateEnumValueList(EnumType);
}
return default(object);
}
private List<object> CreateEnumValueList(Type enumType)
{
return Enum.GetNames(enumType)
.Select(name => Enum.Parse(enumType, name))
.ToList();
}
}
Now we can use it to set our ComboBox items like this:
<ComboBox ItemsSource="{e:EnumCollection EnumType=model:ContactType}"
SelectedItem="{Binding SelectedContactType}" />
The drawback with this approach is that it only works if we want to use all values of an enum on the Control.
Hope this is helpful!