lepoco/wpfui · error · InvalidOperationException

The {pageType} page does not have a parameterless constructo

Error message

The {pageType} page does not have a parameterless constructor. If you are using {typeof(INavigationViewPageProvider)} do not navigate initially and don't use Cache or Precache.

What it means

The final fallback in CreateInstance: after the DI branch and the dataContext branch, the activator looks for a public parameterless constructor via FindParameterlessConstructor. If none exists it throws InvalidOperationException. This fires on the non-DI code path (or when DI is not configured) for pages that only define parameterized constructors.

Source

Thrown at src/Wpf.Ui/Controls/NavigationView/NavigationViewActivator.cs:87

                return instance;
            }
        }
        else if (dataContext != null)
#else
        if (dataContext != null)
#endif
        {
            instance = InvokeElementConstructor(pageType, dataContext);

            if (instance != null)
            {
                return instance;
            }
        }

        ConstructorInfo emptyConstructor =
            FindParameterlessConstructor(pageType)
            ?? throw new InvalidOperationException(
                $"The {pageType} page does not have a parameterless constructor. If you are using {typeof(INavigationViewPageProvider)} do not navigate initially and don't use Cache or Precache."
            );
        instance = emptyConstructor.Invoke(null) as FrameworkElement;
        SetDataContext(instance, dataContext);

        return instance;
    }

#if NET48_OR_GREATER || NETCOREAPP3_0_OR_GREATER
    private static object? ResolveConstructorParameter(Type tParam, object? dataContext)
    {
        if (dataContext != null && dataContext.GetType() == tParam)
        {
            return dataContext;
        }

        return ControlsServices.ControlsServiceProvider?.GetService(tParam);
    }

View on GitHub (pinned to ffebacd610)

Solutions

  1. Add an explicit public parameterless constructor to the page.
  2. Register an INavigationViewPageProvider / IServiceProvider so the page is resolved via DI instead of reflection.
  3. Supply a dataContext whose type matches one of the page's constructors.
  4. Do not set Cache/Precache or initial navigation for pages that require DI.

Example fix

// before
public class SettingsPage : UserControl
{
    public SettingsPage(ISettingsService svc) { ... }
}

// after
public class SettingsPage : UserControl
{
    public SettingsPage() : this(new SettingsService()) { }
    public SettingsPage(ISettingsService svc) { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

var hasParameterless = typeof(TPage).GetConstructor(Type.EmptyTypes) is not null;
if (!hasParameterless && ControlsServices.ControlsServiceProvider is null)
{
    throw new InvalidOperationException($"{typeof(TPage)} needs a parameterless ctor or DI.");
}

Type guard

static bool HasUsableConstructor(Type t) =>
    t.GetConstructor(Type.EmptyTypes) is not null || ControlsServices.ControlsServiceProvider is not null;

Try / catch

try { navView.Navigate<TPage>(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("parameterless constructor"))
{
    _logger.LogError(ex, "No parameterless ctor for {Page}", typeof(TPage));
}

Prevention

When it happens

Trigger: A page that defines only constructors taking arguments is navigated to without a registered IServiceProvider/INavigationViewPageProvider and without a matching dataContext constructor.

Common situations: A page written for DI (constructor takes services) being opened in a context where DI is not wired; removing the implicit parameterless constructor after adding a custom one; design-time or unit-test hosting that lacks the full DI container.

Related errors


AI-assisted analysis of lepoco/wpfui@ffebacd610 (2026-08-13). Data as JSON: /api/errors/e3a9165484eeb0fe. Report an issue: GitHub.