dotnet/wpf · error · ArgumentException
SR.Format(SR.MustBeFrameworkOr3DDerived, value.Name)
Error message
SR.Format(SR.MustBeFrameworkOr3DDerived, value.Name)
What it means
The FrameworkElementFactory.Type setter only accepts types derived from FrameworkElement, FrameworkContentElement, or Visual3D. Assigning any other Type throws this ArgumentException naming the offending type. FrameworkElementFactory can only instantiate WPF framework-level elements for template content.
Solutions
- Only assign types deriving from FrameworkElement (e.g. TextBlock, Border), FrameworkContentElement, or Visual3D.
- For non-visual data, keep the CLR object as DataContext/Content and use a FrameworkElement-derived presenter inside the template.
- Pre-validate the candidate Type before assignment with the same IsAssignableFrom checks WPF uses.
Example fix
// before factory.Type = typeof(MyDataRecord); // throws // after factory.Type = typeof(ContentPresenter); // FrameworkElement-derived, show data via bindings
Defensive patterns
Strategy: validation
Validate before calling
static bool IsSupportedElementType(Type t) =>
t is not null &&
(typeof(FrameworkElement).IsAssignableFrom(t) ||
typeof(FrameworkContentElement).IsAssignableFrom(t) ||
typeof(Visual3D).IsAssignableFrom(t));
if (!IsSupportedElementType(candidateType))
throw new ArgumentException($"{candidateType.Name} must derive from FrameworkElement, FrameworkContentElement, or Visual3D."); Type guard
bool IsValidFactoryType(Type? t) => t is not null && (typeof(FrameworkElement).IsAssignableFrom(t) || typeof(FrameworkContentElement).IsAssignableFrom(t) || typeof(Visual3D).IsAssignableFrom(t));
Try / catch
try { factory.Type = candidateType; }
catch (ArgumentException ex) { logger.LogWarning(ex, "Unsupported factory type {Type}", candidateType.Name); } Prevention
- Only pass typeof(...) of known WPF controls into FrameworkElementFactory.
- For generic CLR data, bind via DataContext rather than instantiating the type in a template.
- Add a unit test that enumerates your generated template types and asserts hierarchy support.
When it happens
Trigger: Setting factory.Type to typeof(string), a POCO, a struct, a non-Visual custom class, or any type outside the three supported hierarchies.
Common situations: Trying to host arbitrary CLR objects directly in a template instead of binding data; generating templates via reflection where the fetched Type is a model type, not a control; targeting types from assemblies not referencing PresentationFramework.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- SR.FrameworkElementFactoryAlreadyParented
- SR.FrameworkElementFactoryCannotAddText
- SR.NameNotEmptyString
- Animation_ChildMustBeKeyFrame
- Animation_ChildMustBeKeyFrame
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/ba1d1a1e320ddd69.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkElementFactory.cs:87
{
if (_sealed)
{
throw new InvalidOperationException(SR.Format(SR.CannotChangeAfterSealed, "FrameworkElementFactory"));
}
if (_text != null)
{
throw new InvalidOperationException(SR.FrameworkElementFactoryCannotAddText);
}
if ( value != null ) // We allow null up until Seal
{
// If non-null, must be derived from one of the supported types
if (!typeof(FrameworkElement).IsAssignableFrom(value) &&
!typeof(FrameworkContentElement).IsAssignableFrom(value) &&
!typeof(Visual3D).IsAssignableFrom(value))
{
throw new ArgumentException(SR.Format(SR.MustBeFrameworkOr3DDerived, value.Name));
}
}
// It is possible that _type is null when a FEF is created for text content within a tag
_type = value;
// If this is a KnownType in the BamlSchemaContext, then there is a faster way to create
// an instance of that type than using Activator.CreateInstance. So in that case
// save the delegate for later creation.
WpfKnownType knownType = null;
if (_type != null)
{
knownType = XamlReader.BamlSharedSchemaContext.GetKnownXamlType(_type) as WpfKnownType;
}
_knownTypeFactory = knownType?.DefaultConstructor;
}
}
View on GitHub (pinned to 81131a70a4)