dotnet/wpf · error · ArgumentException
SR.VisualCollection_EntryInUse
Error message
SR.VisualCollection_EntryInUse
What it means
Thrown by the VisualCollection indexer setter when trying to replace a non-null child at an index with a different visual that is already attached elsewhere (has a parent or is a visual-tree root). WPF allows a visual to have only one parent; the slot check (child != null combined with value already parented) raises ArgumentException before VisualHasParent is evaluated for re-parenting rules.
Solutions
- Detach the incoming visual from its current parent (remove it from its old parent's children) before assigning it to the new index.
- Ensure IsRootElement visuals (visual targets/roots) are never assigned into a child slot.
- Null the slot or use a fresh visual instance instead of a shared one.
- Verify with VisualTreeHelper.GetParent(value) == null before the swap.
Example fix
// before
oldPanel.Children.Remove(sharedVisual);
collection[index] = sharedVisual; // if collection[index] != null and shared still parented elsewhere -> EntryInUse
// after
var oldOwner = VisualTreeHelper.GetParent(sharedVisual) as Visual;
(oldOwner as UIElement)?.EnsureVisuals().Remove(sharedVisual); // detach from any tree first
if (collection[index] == null)
{
collection[index] = sharedVisual;
} Defensive patterns
Strategy: validation
Validate before calling
if (collection[index] != null &&
(VisualTreeHelper.GetParent(value) != null || value.IsRootElement))
return; // detach 'value' from its current tree first
collection[index] = value; Type guard
static bool IsAttachable(Visual v) => VisualTreeHelper.GetParent(v) == null && !v.IsRootElement;
Try / catch
try { collection[index] = value; }
catch (ArgumentException) { /* incoming visual still owned elsewhere */ } Prevention
- Detach the incoming visual from its old parent before replacing a non-null slot.
- Never assign VisualTarget root visuals into child collections.
- Don't share one visual instance between multiple parents.
- Use Add/Remove pairs rather than raw indexer swaps when moving visuals.
When it happens
Trigger: Assigning collection[index] = someVisual while (a) the current child at that index is non-null and (b) someVisual._parent is not null or someVisual.IsRootElement is true — i.e. swapping an existing child for a visual that is itself already connected to another tree.
Common situations: Moving a shared visual (e.g. an adorner or overlay element) into a second parent without detaching it first; templating code that swaps slot contents with recycled visuals still parented elsewhere.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SR.VisualCollection_VisualHasParent
- SR.Collection_BadRank
- " }} " element found. Expected fixed page element ( }} ).
- ' ' ContentType is not valid.
- ' ' ID is not a valid XSD ID.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/9ffc97006798ded9.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/VisualCollection.cs:337
}
set
{
VerifyAPIReadWrite(value);
ArgumentOutOfRangeException.ThrowIfNegative(index);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(index, _size);
Visual child = _items[index];
if ((value == null) && (child != null))
{
DisconnectChild(index);
}
else if (value != null)
{
if (child != null)
{
throw new System.ArgumentException(SR.VisualCollection_EntryInUse);
}
if ((value._parent != null) // Only a visual that isn't a visual parent or
|| value.IsRootElement) // are a root node of a visual target can be set into the collection.
{
throw new System.ArgumentException(SR.VisualCollection_VisualHasParent);
}
ConnectChild(index, value);
}
}
}
/// <summary>
/// Sets the specified visual at the specified index into the child
/// collection. It also corrects the parent.
/// Note that the function requires that _item[index] == null and it
/// also requires that the passed in child is not connected to another Visual.
/// </summary>View on GitHub (pinned to 81131a70a4)