Reputation: 3676
I have an ObjectDataProvider for getting a list of enum members:
<ObjectDataProvider x:Key="GetEnumContents" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="Data:Status"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
which I then use with:
<ComboBox SelectedItem="{Binding Status, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding Source={StaticResource GetEnumContents}}" />
In the same window, I'd then like to have a combo box for a different enum. How do I pass the enum type from the ComboBox declaration?
I've seen solutions to similar problems something like:
Path="MethodParameters[0]"
but here I don't want to bind the parameter to anything, I just want to hard-code it in the ComboBox declaration.
Any ideas?
Upvotes: 2
Views: 1287
Reputation: 16991
ObjectDataProvider
doesn't support that kind of functionality, but you can "fake" it with the clever abuse usage of a Binding
and an IValueConverter
.
First, the IValueConverter
:
class EnumConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return Enum.GetValues((Type)parameter);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Here is how you use it:
<Window
x:Class="EnumTest.MainWindow"
[...snip...]
xmlns:local="clr-namespace:EnumTest"
Title="MainWindow"
Width="800"
Height="450"
mc:Ignorable="d">
<Window.Resources>
<local:EnumConverter x:Key="EnumConverter" />
</Window.Resources>
<StackPanel>
<ComboBox ItemsSource="{Binding Converter={StaticResource EnumConverter}, ConverterParameter={x:Type local:MyEnum1}}" />
<ComboBox ItemsSource="{Binding Converter={StaticResource EnumConverter}, ConverterParameter={x:Type local:MyEnum2}}" />
</StackPanel>
</Window>
Some Test Enums:
enum MyEnum1
{
Red,
Green,
Blue,
}
enum MyEnum2
{
Cat,
Dog,
Fish,
Bird,
}
This produces the following output:
This takes advantage of the fact that you can pass an extra parameter to an IValueConverter
, which I use to pass the Type
of the enumeration to the converter. The converter just calls Enum.GetNames
on that argument, and returns the result. The actual Binding
will actually be bound to whatever the DataContext
of the ComboBox
happens to be. The EnumConverter
just happily ignores it and operates on the parameter instead.
UPDATE
It works even better by binding directly to the type, skipping the ConverterParameter
entirely, like so:
<ComboBox ItemsSource="{Binding Source={x:Type local:MyEnum1}, Converter={StaticResource EnumConverter}}" />
With adjustments to the converter:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return Enum.GetValues((Type)value);
}
Same result with less typing, and easier to understand, code.
Upvotes: 2