dotnet/wpf · error · InvalidOperationException

SR.CantSetOwnerToClosedWindow

Error message

SR.CantSetOwnerToClosedWindow

What it means

Window.Owner setter throws InvalidOperationException when the candidate owner window has already been closed and disposed (_disposed == true). A disposed window has no valid HWND and cannot serve as an owner. The check is inside the Owner setter when value.IsSourceWindowNull is true.

Solutions

  1. Verify the candidate owner is alive before assigning: check !owner.IsDisposed (track via Closed event) or Application.Current.Windows.Contains(owner).
  2. Pick a live window such as Application.Current.MainWindow as owner.
  3. Set Owner before the candidate window can be closed, or drop ownership (leave Owner null).

Example fix

// before
dlg.Owner = _cachedParent; // may be closed
// after
if (_cachedParent != null && Application.Current.Windows.Contains(_cachedParent))
    dlg.Owner = _cachedParent;
Defensive patterns

Strategy: validation

Validate before calling

bool isValidOwner(Window w) => w != null && Application.Current.Windows.Contains(w);

Type guard

bool IsLiveWindow(Window w) => w != null && !w.IsDisposed(); // track via Closed event flag

Try / catch

try { dlg.Owner = candidate; }
catch (InvalidOperationException) { dlg.Owner = Application.Current.MainWindow; }

Prevention

When it happens

Trigger: Assigning window.Owner to a Window instance that was already closed (Close called and window disposed).

Common situations: Caching a parent window reference that the user closed earlier, then using it to open a new dialog; long-lived references to closed windows in singleton patterns.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Window.cs:1241

                // is not allowed
                VerifyApiSupported();
                VerifyContextAndObjectState();
                if (value == this)
                {
                    throw new ArgumentException(SR.CannotSetOwnerToItself);
                }

                if (_showingAsDialog)
                {
                    throw new InvalidOperationException(SR.CantSetOwnerAfterDialogIsShown);
                }

                if (value != null && value.IsSourceWindowNull)
                {
                    // Try to be specific in the error message.
                    if (value._disposed)
                    {
                        throw new InvalidOperationException(SR.CantSetOwnerToClosedWindow);
                    }
                    throw new InvalidOperationException(SR.CantSetOwnerWhosHwndIsNotCreated);
                }

                if ( _ownerWindow == value )
                {
                    return;
                }

                if (!_disposed)
                {
                    // Check to see if value is already a child of this window.
                    // If yes, throw Exception
                    if (value != null)
                    {
                        WindowCollection ownedWindows = OwnedWindows;
                        for (int i = 0; i < ownedWindows.Count; i++)
                        {

View on GitHub (pinned to 81131a70a4)