dotnet/wpf · error · InvalidOperationException

SR.TypeMetadataCannotChangeAfterUse

Error message

SR.TypeMetadataCannotChangeAfterUse

What it means

The AffectsMeasure property setter throws InvalidOperationException when the metadata has been sealed. Once a dependency property is registered (or metadata is added via OverrideMetadata/AddOwner), WPF seals it so layout-related flags can no longer change; mutating them afterwards would invalidate already-computed layout information.

Solutions

  1. Set AffectsMeasure in the constructor or FrameworkPropertyMetadataOptions flags BEFORE passing the metadata to Register/OverrideMetadata/AddOwner.
  2. Create a fresh FrameworkPropertyMetadata instance with the desired options instead of mutating the sealed one.
  3. Check metadata.IsSealed before setting and fail fast with a clear message in debug builds.

Example fix

// before
FrameworkPropertyMetadata m = (FrameworkPropertyMetadata)MyProperty.GetMetadata(typeof(MyControl));
m.AffectsMeasure = true; // throws once sealed
// after
var m = new FrameworkPropertyMetadata(defaultValue, FrameworkPropertyMetadataOptions.AffectsMeasure);
DependencyProperty.Register("MyProperty", typeof(double), typeof(MyControl), m);
Defensive patterns

Strategy: validation

Validate before calling

if (metadata.IsSealed)
    throw new InvalidOperationException("Metadata already sealed; create a new FrameworkPropertyMetadata before setting AffectsMeasure.");

Type guard

static bool CanModify(FrameworkPropertyMetadata m) => !m.IsSealed;

Try / catch

try { meta.AffectsMeasure = true; }
catch (InvalidOperationException ex) { log.Warn("Metadata sealed; recreate with FrameworkPropertyMetadataOptions.AffectsMeasure", ex); }

Prevention

When it happens

Trigger: Setting metadata.AffectsMeasure = true on a FrameworkPropertyMetadata instance after that metadata was passed to DependencyProperty.Register, OverrideMetadata, or AddOwner (i.e. after metadata.Sealed is true).

Common situations: Toggling AffectsMeasure at runtime in response to user settings; a static constructor order issue where another type's static initializer registered the metadata first; unit tests reusing a cached metadata object across registrations.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/56b3bc760c8bd208. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkPropertyMetadata.cs:319

            }

            if (IsFlagSet(FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender, flags))
            {
                SubPropertiesDoNotAffectRender = true;
            }
        }

        /// <summary>
        ///     Property affects measurement
        /// </summary>
        public bool AffectsMeasure
        {
            get { return ReadFlag(MetadataFlags.FW_AffectsMeasureID); }
            set
            {
                if (IsSealed)
                {
                    throw new InvalidOperationException(SR.TypeMetadataCannotChangeAfterUse);
                }

                WriteFlag(MetadataFlags.FW_AffectsMeasureID, value);
            }
        }

        /// <summary>
        ///     Property affects arragement
        /// </summary>
        public bool AffectsArrange
        {
            get { return ReadFlag(MetadataFlags.FW_AffectsArrangeID); }
            set
            {
                if (IsSealed)
                {
                    throw new InvalidOperationException(SR.TypeMetadataCannotChangeAfterUse);
                }

View on GitHub (pinned to 81131a70a4)