dotnet/wpf · error · InvalidOperationException

SR.Format(SR.TableInvalidParentNodeType…

Error message

SR.Format(SR.TableInvalidParentNodeType, newParent.GetType().ToString())

What it means

TableCell.OnNewParent validates that a cell's new parent is a TableRow (or null). Assigning a TableCell to any other DependencyObject parent throws InvalidOperationException naming the actual parent type, because TableCell can only live in a TableRow's Cells collection.

Solutions

  1. Add the TableCell to a TableRow's Cells collection, not to TableRowGroup/Table
  2. Correct the XAML nesting: Table > TableRowGroup > TableRow > TableCell
  3. When reparenting, ensure newParent is TableRow or null before calling

Example fix

// before
tableRowGroup.Cells.Add(cell); // wrong container
// after
var row = new TableRow();
row.Cells.Add(cell);
tableRowGroup.Rows.Add(row);
Defensive patterns

Strategy: validation

Validate before calling

bool ok = newParent == null || newParent is TableRow;

Type guard

static bool CanParentCell(DependencyObject p) => p is TableRow || p == null;

Try / catch

try { row.Cells.Add(cell); } catch (InvalidOperationException ex) when (ex.Message.Contains("parent")) { /* fix nesting */ }

Prevention

When it happens

Trigger: Programmatically setting a TableCell's parent (via collection add into the wrong collection or direct reparenting APIs) to something that is not a TableRow, e.g. adding a cell to a TableRowGroup or Table directly.

Common situations: Building table markup programmatically and appending cells to the wrong container; XAML with a TableCell directly under TableRowGroup/Table; data-driven table generation with wrong nesting.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/a7f6c50159cd1786. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TableCell.cs:88

        //
        //------------------------------------------------------

        #region Public Methods 

        /// <summary>
        /// Called when tablecell gets new parent
        /// </summary>
        /// <param name="newParent">
        /// New parent of cell
        /// </param>
        internal override void OnNewParent(DependencyObject newParent)
        {
            DependencyObject oldParent = this.Parent;
            TableRow newParentTR = newParent as TableRow;

            if((newParent != null) && (newParentTR == null))
            {
                throw new InvalidOperationException(SR.Format(SR.TableInvalidParentNodeType, newParent.GetType().ToString()));
            }

            if(oldParent != null)
            {
                ((TableRow)oldParent).Cells.InternalRemove(this);
            } 

            base.OnNewParent(newParent);

            if ((newParentTR != null) && (newParentTR.Cells != null)) // keep PreSharp happy
            {
                newParentTR.Cells.InternalAdd(this);
            }
        }

        #endregion Public Methods 

        //------------------------------------------------------

View on GitHub (pinned to 81131a70a4)