dotnet/wpf · error · NotSupportedException
SR.Format(SR.ModifyingLogicalTreeViaStylesNotImplemented…
Error message
SR.Format(SR.ModifyingLogicalTreeViaStylesNotImplemented, value, "FrameworkElementFactory.SetValue")
What it means
FrameworkElementFactory.SetValue throws NotSupportedException when the value would modify (style) the logical tree. Values such as elements or logical-tree-touching references are not allowed to be set through a style factory because styles must not reparent or modify the logical tree. WPF deliberately disallows this scenario rather than producing undefined behavior at instantiation.
Solutions
- Use factory.AppendChild(childFactory) with a nested FrameworkElementFactory instead of SetValue with an element.
- Set logical-tree properties after template instantiation on the actual element instance.
- If a plain value is intended, verify you are passing a value object, not a UIElement, to SetValue.
Example fix
// before factory.SetValue(ContentPresenter.ContentProperty, new TextBlock()); // after var textFactory = new FrameworkElementFactory(typeof(TextBlock)); factory.AppendChild(textFactory);
Defensive patterns
Strategy: validation
Validate before calling
if (value is UIElement) throw new InvalidOperationException("Use AppendChild, not SetValue, for logical-tree values."); Type guard
static bool IsLogicalTreeValue(object value) => value is UIElement or ContentElement;
Try / catch
try { factory.SetValue(dp, value); }
catch (NotSupportedException) { var child = new FrameworkElementFactory(value.GetType()); factory.AppendChild(child); } Prevention
- Never pass UIElement instances to factory SetValue.
- Model child content with nested FrameworkElementFactory + AppendChild.
- Set element-instance content after template instantiation.
When it happens
Trigger: Calling factory.SetValue(dp, value) where StyleHelper.IsStylingLogicalTree(dp, value) returns true — typically setting a property to a UIElement or a value that would be added to the logical tree via the style.
Common situations: Trying to set a Content or Child property to an element instance on a FrameworkElementFactory; attempting to embed child visuals via factory SetValue instead of AddChild; code translated from templates that worked with direct element construction.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- ' ' must be the root element of a tree, but has a logical…
- SR.CannotBeSelfParent
- SR.CannotBeSelfParent
- SR.CannotBeSelfParent
- SR.CannotModifyLogicalChildrenDuringTreeWalk
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/f23f8c1299f28b41.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkElementFactory.cs:215
if (_sealed)
{
throw new InvalidOperationException(SR.Format(SR.CannotChangeAfterSealed, "FrameworkElementFactory"));
}
ArgumentNullException.ThrowIfNull(dp);
// Value needs to be valid for the DP, or Binding/MultiBinding/PriorityBinding.
// (They all have MarkupExtension, which we don't actually support, see above check.)
if (!dp.IsValidValue(value) && !(value is MarkupExtension) && !(value is DeferredReference))
{
throw new ArgumentException(SR.Format(SR.InvalidPropertyValue, value, dp.Name));
}
// Styling the logical tree is not supported
if (StyleHelper.IsStylingLogicalTree(dp, value))
{
throw new NotSupportedException(SR.Format(SR.ModifyingLogicalTreeViaStylesNotImplemented, value, "FrameworkElementFactory.SetValue"));
}
if (dp.ReadOnly)
{
// Read-only properties will not be consulting FrameworkElementFactory for value.
// Rather than silently do nothing, throw error.
throw new ArgumentException(SR.Format(SR.ReadOnlyPropertyNotAllowed, dp.Name, GetType().Name));
}
ResourceReferenceExpression resourceExpression = value as ResourceReferenceExpression;
DynamicResourceExtension dynamicResourceExtension = value as DynamicResourceExtension;
object resourceKey = null;
if( resourceExpression != null )
{
resourceKey = resourceExpression.ResourceKey;
}
else if( dynamicResourceExtension != null )View on GitHub (pinned to 81131a70a4)