Binding a ComboBox to an enum nested in a class

后端 未结 2 2105
孤独总比滥情好
孤独总比滥情好 2020-12-03 18:09

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

相关标签:
2条回答
  • 2020-12-03 18:47

    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.

    0 讨论(0)
  • 2020-12-03 18:52

    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.

    0 讨论(0)
提交回复
热议问题