dotnet/wpf · error · InvalidOperationException

SR.ListElementItemNotAChildOfList

Error message

SR.ListElementItemNotAChildOfList

What it means

List.GetListItemIndex computes the index of a ListItem within a List, but first validates that the item is actually a child of this list. If item.Parent is not this List, an InvalidOperationException with SR.ListElementItemNotAChildOfList is thrown. ValidateVisual calls this during layout of list numbering.

Solutions

  1. Ensure the ListItem passed to GetListItemIndex has Parent set to this List instance.
  2. Re-add the ListItem to the List via Blocks collection before querying its index.
  3. Check item.Parent == list before calling, and handle/rethrow appropriately.
  4. Rebuild the document tree if elements were manually re-parented.

Example fix

// before
int idx = myList.GetListItemIndex(itemFromOtherList);
// after
if (item.Parent == myList)
{
    int idx = myList.GetListItemIndex(item);
}
Defensive patterns

Strategy: validation

Validate before calling

bool isChild = ReferenceEquals(item?.Parent, list);
if (!isChild) return -1; // or throw descriptive error

Type guard

static bool IsChildOf(List list, ListItem item) => item?.Parent == list;

Try / catch

try { int idx = list.GetListItemIndex(item); }
catch (InvalidOperationException) { /* item not owned by this list */ }

Prevention

When it happens

Trigger: Calling List.GetListItemIndex with a ListItem that belongs to a different List (or no List); visual validation of a ListItem that was moved/reparented without updating references.

Common situations: Programmatically moving a ListItem between two List FlowDocuments; cloning content and passing the clone's item to the original List; incorrect TextElement parentage after document surgery.

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/d909e6bb2cc1ec0c. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/List.cs:184

        /// this List. This index is defined to be a sequential counter of ListElementItems only 
        /// (skipping other elements) among this List's immediate children. 
        /// 
        /// The list item index of the first child of type ListItem is specified by 
        /// this.StartListIndex, which has a default value of 1. 
        /// 
        /// The index returned by this method is used in the formation of some ListItem 
        /// markers such as "(b)" and "viii." (as opposed to others, like disks and wedges, 
        /// which are not sequential-position-dependent). 
        /// </summary>
        /// <param name="item">The item whose index is to be returned.</param>
        /// <returns>Returns the index of a specified ListItem.</returns>
        internal int GetListItemIndex(ListItem item)
        {
            // Check for valid arg
            ArgumentNullException.ThrowIfNull(item);
            if (item.Parent != this)
            {
                throw new InvalidOperationException(SR.ListElementItemNotAChildOfList);
            }

            // Count ListItem siblings (not other element types) back to first item.
            int itemIndex = StartIndex;
            TextPointer textNav = new TextPointer(this.ContentStart);
            while (textNav.CompareTo(this.ContentEnd) != 0)
            {
                // ListItem is a content element, so look for ElementStart runs only
                if (textNav.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart)
                {
                    DependencyObject element = textNav.GetAdjacentElementFromOuterPosition(LogicalDirection.Forward);
                    if (element is ListItem)
                    {
                        if (element == item)
                        {
                            break;
                        }
                        if (itemIndex < int.MaxValue)

View on GitHub (pinned to 81131a70a4)