lepoco/wpfui · error · InvalidCastException

PageType of the ${typeof(INavigationViewItem)} must be deriv

Error message

PageType of the ${typeof(INavigationViewItem)} must be derived from {typeof(FrameworkElement)}. {pageType} is not.

What it means

NavigationViewActivator.CreateInstance rejects any page type that is not assignable to FrameworkElement by throwing InvalidCastException. WPF UI navigation only renders FrameworkElement-derived content (Page, UserControl, Window-embedded controls), so a type that fails this check can never be hosted. This is a hard contract check performed before any constructor logic runs.

Source

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

// ReSharper disable once CheckNamespace
namespace Wpf.Ui.Controls;

/// <summary>
/// Internal activator for creating content instances of the navigation view items.
/// </summary>
internal static class NavigationViewActivator
{
    /// <summary>
    /// Creates new instance of type derived from <see cref="FrameworkElement"/>.
    /// </summary>
    /// <param name="pageType"><see cref="FrameworkElement"/> to instantiate.</param>
    /// <param name="dataContext">Additional context to set.</param>
    /// <returns>Instance of the <see cref="FrameworkElement"/> object or <see langword="null"/>.</returns>
    public static FrameworkElement? CreateInstance(Type pageType, object? dataContext = null)
    {
        if (!typeof(FrameworkElement).IsAssignableFrom(pageType))
        {
            throw new InvalidCastException(
                $"PageType of the ${typeof(INavigationViewItem)} must be derived from {typeof(FrameworkElement)}. {pageType} is not."
            );
        }

        if (DesignerHelper.IsInDesignMode)
        {
            return new Page
            {
                Content = new TextBlock
                {
                    Text =
                        "Pages are not rendered while using the Designer. Edit the page template directly.",
                },
            };
        }

        FrameworkElement? instance;

View on GitHub (pinned to ffebacd610)

Solutions

  1. Point TargetPageType at a UserControl or Page that derives from FrameworkElement.
  2. If you intend to navigate by ViewModel, introduce a View-ViewModel mapping in an INavigationViewPageProvider and resolve the View type.
  3. Double-check the XAML x:Name/Type resolution to ensure the symbol is the view, not a sibling model with the same name.

Example fix

// before
<ui:NavigationViewItem TargetPageType="{x:Type vm:DashboardViewModel}" />

// after
<ui:NavigationViewItem TargetPageType="{x:Type views:DashboardPage}" />
Defensive patterns

Strategy: validation

Validate before calling

if (!typeof(FrameworkElement).IsAssignableFrom(viewItem.TargetPageType))
{
    throw new ArgumentException(
        $"TargetPageType {viewItem.TargetPageType} must derive from FrameworkElement.");
}

Type guard

static bool IsValidPageType(Type? t) => t is not null && typeof(FrameworkElement).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface;

Try / catch

try { navView.Navigate(pageType); }
catch (InvalidCastException ex) when (ex.Message.Contains("must be derived from"))
{
    _logger.LogError("TargetPageType {Type} is not a FrameworkElement", pageType);
}

Prevention

When it happens

Trigger: An INavigationViewItem.TargetPageType (or a Navigate call's generic type argument) is set to a class/struct that does not inherit FrameworkElement - e.g. a plain ViewModel, a record, a Window subclass, or an interface.

Common situations: Accidentally binding TargetPageType to a ViewModel instead of its View; navigating to a data model type; refactoring a page into a non-FrameworkElement base class; copy/paste of a type name from XAML that resolves to the wrong symbol.

Related errors


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