dotnet/wpf · error · ArgumentException
SR.FrameworkElementFactoryAlreadyParented
Error message
SR.FrameworkElementFactoryAlreadyParented
What it means
FrameworkElementFactory.AppendChild throws this ArgumentException when the child factory already has a parent (_parent != null). Each factory node can belong to at most one tree; re-parenting an existing node elsewhere is rejected to keep the factory graph a strict tree.
Solutions
- Create a new FrameworkElementFactory instance for each parent instead of reusing one instance.
- Extract a builder method that constructs a fresh child factory per call site.
- Check child._parent-equivalent state (or track parents yourself) before appending.
Example fix
// before var shared = new FrameworkElementFactory(typeof(TextBlock)); parentA.AppendChild(shared); parentB.AppendChild(shared); // throws // after parentA.AppendChild(MakeTextChild()); parentB.AppendChild(MakeTextChild()); // fresh instance per parent static FrameworkElementFactory MakeTextChild() => new(typeof(TextBlock));
Defensive patterns
Strategy: validation
Validate before calling
// track parents yourself, WPF's _parent is internal
if (parents.ContainsKey(child))
throw new InvalidOperationException("Child factory already belongs to another parent; create a new instance.");
parent.AppendChild(child);
parents[child] = parent; Try / catch
try { parent.AppendChild(child); }
catch (ArgumentException) { parent.AppendChild(CloneFactory(child)); } Prevention
- Never share FrameworkElementFactory instances across templates or parents.
- Use factory-returning builder methods instead of shared singletons.
- Add a debug assertion that each factory is appended exactly once.
When it happens
Trigger: Appending the same FrameworkElementFactory instance to two parents, or appending a factory that was already added to another template's tree.
Common situations: Reusing a shared child factory (e.g. a common header factory) in multiple templates; copy-paste template builders that forget to new up a child per parent.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- SR.NameNotEmptyString
- SR.AbsoluteUriNotAllowed
- SR.CollectionCannotContainNulls
- SR.Format(SR.MustBeFrameworkOr3DDerived, value.Name)
- SR.Format(SR.NotAmbientProperty…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/82272e84818cd147.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkElementFactory.cs:167
}
/// <summary>
/// Add a factory child to this factory
/// </summary>
/// <param name="child">Child to add</param>
public void AppendChild(FrameworkElementFactory child)
{
if (_sealed)
{
throw new InvalidOperationException(SR.Format(SR.CannotChangeAfterSealed, "FrameworkElementFactory"));
}
ArgumentNullException.ThrowIfNull(child);
if (child._parent != null)
{
throw new ArgumentException(SR.FrameworkElementFactoryAlreadyParented);
}
if (_text != null)
{
throw new InvalidOperationException(SR.FrameworkElementFactoryCannotAddText);
}
// Build tree of factories
if (_firstChild == null)
{
_firstChild = child;
_lastChild = child;
}
else
{
_lastChild._nextSibling = child;
_lastChild = child;
}View on GitHub (pinned to 81131a70a4)