Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reference nested enum type from XAML

Tags:

c#

xaml

I can't seem to reference a public nested enum type from XAML. I have a class

namespace MyNamespace
{
  public class MyClass
  {
    public enum MyEnum
    {
       A,
       B,
    }
  }
}

And I try to reference MyEnum in Xaml like this:

xmlns:MyNamespace="clr-namespace:MyNamespace;assembly=MyApp"
....

{x:Type MyNamespace:MyClass:MyEnum}    // DOESN'T WORK

but VS complains it can't find public type MyEnum. I also tried using the + syntax based on one of the answers to this post...

{x:Type MyNamespace:MyClass+MyEnum}    // DOESN'T WORK

but that doesn't work either.

Note that x:Static does work with the + syntax:

{x:Static MyNamespace:MyClass+MyEnum.A}  // WORKS

And if I move MyEnum out of MyClass I can reference it too. But not if it's nested...

So what am I missing? How do I reference a nested enum from XAML using x:Type? (And note, I'm not trying to instantiate anything, just reference the type).

UPDATE

It looks like this is just a bug with the VS 2010 designer. The designer complains that Type MyNamespace:MyClass+MyEnum was not found. But the application appears to run and properly access the nested type. I tried this with a nested class too, and it works at run time.

Possible open bug: http://social.msdn.microsoft.com/forums/en-US/wpf/thread/12f3e120-e217-4eee-ab49-490b70031806/

Related thread: Design time error while writing Nested type in xaml

like image 239
hashlock Avatar asked Nov 13 '12 20:11

hashlock


1 Answers

A bit late here, but I used a markup extension and then used the following references in my xaml to reference the nested enum in a combobox:

xmlns:MyNamespace="clr-namespace:MyNamespace;assembly=MyApp"

...

ItemsSource="{Binding Source={resource:EnumBindingSource {x:Type MyNamespace:MyClass+MyEnum}}}"

The code for the MarkupExtension was taken from here

public class EnumBindingSourceExtension : MarkupExtension
{
    private Type _enumType;
    public Type EnumType
    {
        get { return this._enumType; }
        set
        {
            if (value != this._enumType)
            {
                if (null != value)
                {
                    Type enumType = Nullable.GetUnderlyingType(value) ?? value;
                    if (!enumType.IsEnum)
                        throw new ArgumentException("Type must be for an Enum.");
                }

                this._enumType = value;
            }
        }
    }

    public EnumBindingSourceExtension() { }

    public EnumBindingSourceExtension(Type enumType)
    {
        this.EnumType = enumType;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (null == this._enumType)
            throw new InvalidOperationException("The EnumType must be specified.");

        Type actualEnumType = Nullable.GetUnderlyingType(this._enumType) ?? this._enumType;
        Array enumValues = Enum.GetValues(actualEnumType);

        if (actualEnumType == this._enumType)
            return enumValues;

        Array tempArray = Array.CreateInstance(actualEnumType, enumValues.Length + 1);
        enumValues.CopyTo(tempArray, 1);
        return tempArray;
    }
}
like image 115
Devin Avatar answered Nov 03 '22 20:11

Devin