I had innocentlly come to the point in my application (and my learning curve) where I need to set the properties of my entity in the GUI via a ComboBox. Specifically, in the Person
form, there is a Gender
field, and this field should be a ComboBox
where the user can choose Male
, Female
and Unspecified
options.
Of course, this ComboBox must be TwoWay data-bound to the Gender
property of my Person
ViewModel.
Well, I first thought "obviously, I should create an enum, then use that enum as the cornerstone for either the Gender
property, and the ComboBox
datasource, to the point that, if I change the enum itself, I don't even need to change either the Person
class or the form XAML.
The problem is: EVERY example of implementing a should-be-simple use of enum
like I described is quite contorted, making use of helper classes, ValueConverter
s, ObjectProvider
s and so on. That seems very odd, considering the "should-be-simple" part...
So, the questions are:
- "Was ComboBox in WPF DESIGNED to be used with Enums in the first place? Or is this obvious choice actually an artificial constraint that makes things more complicated than they should?"
- "How is ComboBox in WPF supposed to be used then, if not with Enum. What is the canonical way for it to be used, regarding the obvious application of two-way databinding a bunch of values to a ViewModel property?"
Thanks for reading.
Final code, following Sheridan's answer transformed to a Dictionary instead of IEnumerable:
In ViewModel which contains the SelectedPerson.Gender
property and where Gender
enum is in the available namespaces:
// this won't be set, so only getter needed, I think
// Using dictionary as a placeholder for i18n implementation.
public Dictionary<Gender, String> Genders {
get { return new Dictionary<Gender,string> {
{Gender.Unspecified, "Não especificado"},
{Gender.Female, "Feminino"},
{Gender.Male, "Masculino"}
};
}
}
And in XAML:
<ComboBox
ItemsSource="{Binding Genders}"
DisplayMemberPath="Value"
SelectedValuePath="Key"
SelectedValue="{Binding SelectedPerson.Gender, Mode=TwoWay}"/>
In on hand, this violates what I stated in the question, "no need to change class if enum changes", but if you have display names and i18n, they will have to change anyway, and so you'll have to "update stuff" anyway if enum changes. But enums are not supposed to change often.
Of course, if display names are not needed, then the Enum.GetNames
way is the way to go.