dotnet/wpf · error · ArgumentException

Child cannot be a top level form.

Error message

Child cannot be a top level form.

What it means

WindowsFormsHost cannot embed a top-level Form as its Child: top-level windows own their HWND and cannot be parented inside another control's visual tree (WinOS bug #1030878). The Child property setter throws ArgumentException (message: 'Child cannot be a top level form') when the assigned Control is a Form with TopLevel == true.

Solutions

  1. Set form.TopLevel = false before assigning it to windowsFormsHost.Child.
  2. Prefer a plain UserControl/Control over a Form for embedding.
  3. Refactor the Form's content into a UserControl and host that instead.

Example fix

// before
host.Child = myForm; // myForm.TopLevel == true -> ArgumentException
// after
myForm.TopLevel = false;
myForm.FormBorderStyle = FormBorderStyle.None;
host.Child = myForm;
Defensive patterns

Strategy: validation

Validate before calling

if (control is Form f)
{
    f.TopLevel = false;
    f.FormBorderStyle = FormBorderStyle.None;
}
host.Child = control;

Type guard

bool CanEmbedInHost(System.Windows.Forms.Control c) => !(c is Form f && f.TopLevel);

Try / catch

try { host.Child = control; }
catch (ArgumentException ex) when (ex.Message.Contains("top level"))
{ log.Error("Set Form.TopLevel = false before hosting", ex); }

Prevention

When it happens

Trigger: Assigning a Form (e.g. new MyForm() { TopLevel = true }) to windowsFormsHost.Child; hosting a form created with Application.Run or a designer form without setting TopLevel = false.

Common situations: Migrating a legacy WinForms dialog into a WPF app by dropping the Form into a WindowsFormsHost; code reuse of a Form that was never designed for embedding.

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/1b8d13613d9ddd7c. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsFormsIntegration/System/Windows/Integration/WindowsFormsHost.cs:317

        /// <summary>
        ///     Gets or sets the child control hosted by the WindowsFormsHost element.
        /// </summary>
        public Control Child
        {
            get
            {
                return _hostContainerInternal.Child;
            }
            set
            {
                Control oldChild = Child;
                SWF.Form form = value as SWF.Form;
                if (form != null)
                {
                    if (form.TopLevel)
                    {  //WinOS #1030878 - Can't host top-level forms
                        throw new ArgumentException(SR.Host_ChildCantBeTopLevelForm);
                    }
                    else
                    {
                        form.ControlBox = false;
                    }
                }
                _hostContainerInternal.Child = value;
                if (Child != null)
                {
                    _propertyMap.ApplyAll();

                    Child.Margin = SWF.Padding.Empty;
                    Child.Dock = DockStyle.None;
                    Child.AutoSize = false;
                    Child.Location = SD.Point.Empty;
                    // clear the cached size
                    _priorConstraint = new Size(double.NaN, double.NaN);
                }

View on GitHub (pinned to 81131a70a4)