I have been going crazy with binding a combobox to an enum typed property of a class, where the enum itself is declared in that same class.
I am trying to follow th
Another way of getting the enum values for use as a data source:
<Window.Resources>
<ObjectDataProvider
MethodName="GetValues"
ObjectType="{x:Type sys:Enum}"
x:Key="TestValues">
<ObjectDataProvider.MethodParameters>
<w:Type2
TypeName="w:Test+TestEnum" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
...
ItemsSource="{Binding Source={StaticResource TestValues}}"
Note that you still need the Type2Extension
because of weirdness with TypeExtension
and nested types. But you wouldn't need the extra custom markup extension. This way is better if you'll be using the list in multiple places, as you can declare it in your App.xaml
resources.
What about using x:Type
markup extension?
{w:EnumValues EnumType={x:Type w:Test+TestEnum}}
Except for implementing INotifyPropertyChanged
, I copied your code exactly. I do get the errors that you get, but it seems to run just fine. It is very annoying not to be able to load the designer, though. Nothing I've tried has solved the problem.
I did find this page on MSDN about nested types, and a suggestion in that thread was a custom MarkupExtension
for resolving the nested type name. I'm trying to get it to work, but no luck so far. I get similar errors on Type2Extension
sometimes, and I get "The enum type is not set" with other tweaks.
Aha! There was a bug in how the original author was calling GetType()
! Here's the corrected Type2Extension
and how I was using it:
public class Type2Extension : System.Windows.Markup.TypeExtension {
public Type2Extension() {
}
public Type2Extension( string typeName ) {
base.TypeName = typeName;
}
public override object ProvideValue( IServiceProvider serviceProvider ) {
IXamlTypeResolver typeResolver = (IXamlTypeResolver) serviceProvider.GetService( typeof( IXamlTypeResolver ) );
int sepindex = TypeName.IndexOf( '+' );
if ( sepindex < 0 )
return typeResolver.Resolve( TypeName );
else {
Type outerType = typeResolver.Resolve( TypeName.Substring( 0, sepindex ) );
return outerType.Assembly.GetType( outerType.FullName + "+" + TypeName.Substring( sepindex + 1 ) );
}
}
}
And XAML:
ItemsSource="{Binding Source={w:EnumValues {w:Type2 w:Test+TestEnum}}}"
This appears to work fine and the designer loads. I'll be adding Type2Extension
to my own little libraries.
Edit: Oddly enough, if I change this in EnumValues
:
if ( this.EnumType == null )
throw new ArgumentException( "The enum type is not set" );
To this:
if ( this.EnumType == null )
return null;
Then those constructor errors go away. That was the one other thing I changed. However, I am shortly going to post an alternate way of getting enum values.