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

  1. Detach the incoming visual from its current parent (remove it from its old parent's children) before assigning it to the new index.
  2. Ensure IsRootElement visuals (visual targets/roots) are never assigned into a child slot.
  3. Null the slot or use a fresh visual instance instead of a shared one.
  4. 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

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


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)