dotnet/wpf · error

Page can have only Window or Frame as parent.

Error message

Page can have only Window or Frame as parent.

What it means

During OnVisualParentChanged, Page validates that its new visual parent is a Window or Frame. Any other parent (ContentControl, Grid, arbitrary panel) is rejected with this InvalidOperationException because Page relies on WindowService infrastructure only those hosts provide.

Solutions

  1. Host the Page in a Frame: <Frame Source="MyPage.xaml"/> or frame.Content = new MyPage()
  2. Show the Page in a NavigationWindow for top-level navigation hosting
  3. Convert the Page to a UserControl if you only want it embedded in ordinary layout
  4. Never add Page as a child of panels/ContentControl in XAML

Example fix

// before
<Window>
  <Grid>
    <local:MyPage/> <!-- throws -->
  </Grid>
</Window>
// after
<Window>
  <Frame Source="MyPage.xaml"/>
</Window>
Defensive patterns

Strategy: validation

Validate before calling

// XAML-time check: Page may only appear under Window/Frame
bool validHost = page.Parent is Window || page.Parent is Frame;
if (!validHost) throw new InvalidOperationException("Host Page with Frame or NavigationWindow");

Type guard

bool isValidPageHost(object parent) => parent is Window || parent is Frame;

Prevention

When it happens

Trigger: Putting a Page directly as the Content of a Window's inner element (e.g. <Grid><Page/></Grid>), adding a Page to a StackPanel, Border, ContentControl, or any non-Window/non-Frame container.

Common situations: Developers treating Page like a UserControl and embedding it in layout panels; migrating navigation code and hosting pages in ContentControl; design-time previews placing Page in arbitrary containers.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Page.cs:697

                    // tree of an element)

                    // We need this here for the case when Frame is in the style 
                    // of an element
                    if (feParent is Frame)
                    {
                        break;
                    }
                }

                if ((parent is Window) || (parent is Frame))
                {
                    isParentValid = true;
                }
            }

            if (!isParentValid)
            {
                throw new InvalidOperationException(SR.ParentOfPageMustBeWindowOrFrame);
            }
        }

        #endregion Protected Methods
                
        //---------------------------------------------------
        //
        // Private Methods
        //
        //---------------------------------------------------
        #region Private Methods

        private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Page page = (Page) d;
            page.OnContentChanged(e.OldValue, e.NewValue);
        }

View on GitHub (pinned to 81131a70a4)