dotnet/wpf · error · InvalidOperationException

SR.MethodCallNotAllowed

Error message

SR.MethodCallNotAllowed

What it means

VisualDiagnostics.EnableVisualTreeChanged throws InvalidOperationException when called outside an active VisualTreeChanged callback (IsEnableVisualTreeChangedAllowed is false). Visual tree change notification can only be enabled from within a Changed handler so it cannot be left permanently on by arbitrary code.

Solutions

  1. Call EnableVisualTreeChanged only from inside a VisualTreeChanged handler callback
  2. Wrap in try-catch InvalidOperationException if you only opportunistically enable it
  3. Do not rely on EnableVisualTreeChanged for standalone diagnostics; subscribe to VisualTreeChanged events instead

Example fix

// before
VisualDiagnostics.EnableVisualTreeChanged(); // at app startup
// after
// call this only from within the VisualTreeChanged callback:
VisualDiagnostics.EnableVisualTreeChanged();
Defensive patterns

Strategy: try-catch

Validate before calling

if (!insideVisualTreeChangedCallback)
{
    throw new InvalidOperationException("EnableVisualTreeChanged may only be called inside a VisualTreeChanged handler.");
}

Try / catch

try { VisualDiagnostics.EnableVisualTreeChanged(); }
catch (InvalidOperationException) { /* not inside a Changed callback; skip */ }

Prevention

When it happens

Trigger: Calling VisualDiagnostics.EnableVisualTreeChanged() from application code at startup or in an arbitrary method, rather than from inside a VisualTreeChanged event handler callback.

Common situations: Copy-pasted diagnostic setup code enabling changed-notification eagerly; tests calling the enable method directly; tooling that assumed it is a public toggle.

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/0e7158ac513138df. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Diagnostics/VisualDiagnostics.cs:254

        // this class does all the work for checking whether VisualTreeChanged features are
        // enabled, disallowed, etc.  It's a separate class so that its static
        // cctor doesn't run until needed, giving apps time to initialize factors
        // that influence the decisions:  environment, registry, app-context switches, etc.
        private static class EnableHelper
        {
            static EnableHelper()
            {
                if (IsEnabled)
                {
                    s_IsDevMode = GetDevModeFromRegistry();
                    s_IsEnableVisualTreeChangedAllowed = PrecomputeIsEnableVisualTreeChangedAllowed();
                }
            }

            internal static void EnableVisualTreeChanged()
            {
                if (!IsEnableVisualTreeChangedAllowed)
                    throw new InvalidOperationException(SR.Format(SR.MethodCallNotAllowed, nameof(VisualDiagnostics.EnableVisualTreeChanged)));

                s_IsVisualTreeChangedEnabled = true;
            }

            internal static void DisableVisualTreeChanged()
            {
                s_IsVisualTreeChangedEnabled = false;
            }

            internal static bool IsVisualTreeChangeEnabled
            {
                get
                {
                    return IsEnabled &&
                       (s_IsVisualTreeChangedEnabled ||
                        System.Diagnostics.Debugger.IsAttached ||
                        s_isDebuggerCheckDisabledForTestPurposes);
                }

View on GitHub (pinned to 81131a70a4)