{"record":{"id":"a6fa1e7f7dd26c00","repo":"dotnet/wpf","slug":"sr-format-sr-typemustimplementiaddchild-parent-gettype-name","errorCode":null,"errorMessage":"SR.Format(SR.TypeMustImplementIAddChild, parent.GetType().Name)","messagePattern":"SR\\.Format\\(SR\\.TypeMustImplementIAddChild, parent\\.GetType\\(\\)\\.Name\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkElementFactory.cs","lineNumber":650,"sourceCode":"            ref FrugalStructList<ChildPropertyDependent>    resourceDependents)\n        {\n            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml, EventTrace.Level.Verbose, EventTrace.Event.WClientParseFefCrInstBegin);\n\n            FrameworkElement containerAsFE = container as FrameworkElement;\n            bool isContainerAnFE = containerAsFE != null;\n\n            DependencyObject treeNode = null;\n            // If we have text, just add it to the parent.  Otherwise create the child\n            // subtree\n            if (_text != null)\n            {\n                // of FrameworkContentElement parent.  This is the logical equivalent\n                // to what happens when adding a child to a visual collection.\n                IAddChild addChildParent = parent as IAddChild;\n\n                if (addChildParent == null)\n                {\n                    throw new InvalidOperationException(SR.Format(SR.TypeMustImplementIAddChild,\n                                                         parent.GetType().Name));\n                }\n                else\n                {\n                    addChildParent.AddText(_text);\n                }\n            }\n            else\n            {\n                // Factory create instance\n                treeNode = CreateDependencyObject();\n\n                EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml, EventTrace.Level.Verbose, EventTrace.Event.WClientParseFefCrInstEnd);\n\n                // The tree node is either a FrameworkElement or a FrameworkContentElement.\n                //  we'll deal with one or the other...\n                FrameworkObject treeNodeFO = new FrameworkObject(treeNode);\n","sourceCodeStart":632,"sourceCodeEnd":668,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkElementFactory.cs#L632-L668","documentation":"During InstantiateTree, when a factory node holds text content (_text), the framework tries to cast the instantiated parent to IAddChild and call AddText. If the parent type does not implement IAddChild, the text cannot be attached, so an InvalidOperationException naming the parent type is thrown. The factory system relies on IAddChild as the contract for content insertion.","triggerScenarios":"Calling SetText on a FrameworkElementFactory whose parent node instantiates to a type that does not implement IAddChild, then sealing and instantiating the template (e.g. via a ContentPresenter/template expansion).","commonSituations":"Building a factory tree in code where a text-only child factory is nested under a plain FrameworkElement-derived type (like Grid or StackPanel wrappers that historically implement IAddChild, but custom controls may not); refactoring a control so it no longer implements IAddChild while old factory code still sets text on it.","solutions":["Make the parent type implement IAddChild (AddText at minimum) or use a different parent type that does.","Instead of SetText on the child factory, use SetValue with an appropriate property (e.g. TextBlock.TextProperty) on a TextBlock factory.","Remove the SetText call if the parent cannot accept text content."],"exampleFix":"// before\nvar child = new FrameworkElementFactory(typeof(TextBlock));\nchild.SetText(\"hello\"); // parent is a custom panel not implementing IAddChild\n// after\nchild.SetValue(TextBlock.TextProperty, \"hello\");","handlingStrategy":"type-guard","validationCode":"if (parentFactory?.Type is Type t && !typeof(IAddChild).IsAssignableFrom(t))\n    throw new InvalidOperationException($\"{t.Name} cannot receive text; implement IAddChild or set a property\");","typeGuard":"bool CanAddText(object o) => o is IAddChild;","tryCatchPattern":"try { template.LoadContent(); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"IAddChild\")) { /* use SetValue on a property instead */ }","preventionTips":["Prefer SetValue(TextBlock.TextProperty, ...) over SetText on arbitrary parents","Verify parent types implement IAddChild when nesting child factories","Avoid custom non-IAddChild types as factory parents"],"tags":["wpf","template","iaddchild","type-mismatch"],"backgroundTag":"incompatible-source-type","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}