MahApps/MahApps.Metro · error · ArgumentException

Type must be for an Enum.

Error message

Type must be for an Enum.

What it means

EnumBindingSourceExtension is a XAML markup extension that exposes an enum's values for binding. Its EnumType property setter validates that the assigned Type is (or is a Nullable<> of) an enum; if not it throws ArgumentException. The setter handles the nullable case via Nullable.GetUnderlyingType before the IsEnum check.

Source

Thrown at src/MahApps.Metro.Samples/MahApps.Metro.Demo/Markup/EnumBindingSourceExtension.cs:36

        /// <summary>
        /// Gets or sets the type of the Enum.
        /// </summary>
        /// <exception cref="ArgumentException">Value is not an Enum type.</exception>
        [ConstructorArgument("enumType")]
        public Type? EnumType
        {
            get => this.enumType;
            set
            {
                if (value != this.enumType)
                {
                    if (null != value)
                    {
                        var type = Nullable.GetUnderlyingType(value) ?? value;

                        if (!type.IsEnum)
                        {
                            throw new ArgumentException("Type must be for an Enum.");
                        }
                    }

                    this.enumType = value;
                }
            }
        }

        /// <summary>
        /// Initializes a new instance of EnumBindingSourceExtension.
        /// </summary>
        public EnumBindingSourceExtension()
        {
        }

        /// <summary>
        /// Initializes a new instance of EnumBindingSourceExtension.
        /// </summary>

View on GitHub (pinned to 72099e310b)

Solutions

  1. Set EnumType to an actual enum type, e.g. {x:Type local:MyEnum} or in code typeof(MyEnum).
  2. If you need nullable enum binding, use Nullable<MyEnum> (e.g. {x:Type sys:Nullable`1[local:MyEnum]}) — the setter already unwraps Nullable.
  3. Fix the XAML that points to the wrong type; the design-time parser will catch the ArgumentException immediately.

Example fix

<!-- before -->
<ComboBox ItemsSource="{markup:EnumBindingSource EnumType={x:Type local:MySettings}}"/>
<!-- after -->
<ComboBox ItemsSource="{markup:EnumBindingSource EnumType={x:Type local:MyEnum}}"/>
Defensive patterns

Strategy: type-guard

Validate before calling

// Validate the type is an enum (or Nullable<enum>) before assigning
static bool IsEnumType(Type t) {
    if (t is null) return true; // null allowed by the setter
    var underlying = Nullable.GetUnderlyingType(t) ?? t;
    return underlying.IsEnum;
}
if (!IsEnumType(myType)) throw new ArgumentException($"{myType} is not an enum");
ext.EnumType = myType;

Type guard

static bool IsEnumOrNullableEnum(Type? t) {
    if (t is null) return false;
    var underlying = Nullable.GetUnderlyingType(t) ?? t;
    return underlying.IsEnum;
}

Prevention

When it happens

Trigger: Setting EnumType to a non-enum Type — e.g. {x:Type local:MyStruct}, {x:Type sys:Int32} via XAML, or assigning programmatically with a class/struct/int Type. The null/Nullable<int> wrapped check still rejects it because the underlying type is not an enum.

Common situations: XAML mistakenly binds the extension to a class, struct, or primitive instead of an enum. Refactoring a type from enum to something else without updating the XAML. Copy-paste of the markup extension to a non-enum source.

Related errors


AI-assisted analysis of MahApps/MahApps.Metro@72099e310b (2026-08-13). Data as JSON: /api/errors/3dbcf6e48bb0cc45. Report an issue: GitHub.