{"record":{"id":"5f15ff8d37fb62af","repo":"stride3d/stride","slug":"a-part-named-part-logtextbox-must-be-present-in-the","errorCode":null,"errorMessage":"A part named 'PART_LogTextBox' must be present in the ControlTemplate, and must be of type 'RichTextBox'.","messagePattern":"A part named 'PART_LogTextBox' must be present in the ControlTemplate, and must be of type 'RichTextBox'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Presentation.Wpf/Controls/TextLogViewer.cs","lineNumber":296,"sourceCode":"\n        /// <summary>\n        /// Gets or sets whether the log viewer should display fatal messages.\n        /// </summary>\n        public bool ShowFatalMessages { get { return (bool)GetValue(ShowFatalMessagesProperty); } set { SetValue(ShowFatalMessagesProperty, value.Box()); } }\n\n        /// <summary>\n        /// Gets or sets whether the log viewer should display fatal messages.\n        /// </summary>\n        public bool ShowStacktrace { get { return (bool)GetValue(ShowStacktraceProperty); } set { SetValue(ShowStacktraceProperty, value.Box()); } }\n\n        /// <inheritdoc/>\n        public override void OnApplyTemplate()\n        {\n            base.OnApplyTemplate();\n\n            logTextBox = GetTemplateChild(\"PART_LogTextBox\") as RichTextBox;\n            if (logTextBox == null)\n                throw new InvalidOperationException(\"A part named 'PART_LogTextBox' must be present in the ControlTemplate, and must be of type 'RichTextBox'.\");\n\n            var clearLogButton = GetTemplateChild(\"PART_ClearLog\") as ButtonBase;\n            if (clearLogButton != null)\n            {\n                clearLogButton.Click += ClearLog;\n            }\n\n            var previousResultButton = GetTemplateChild(\"PART_PreviousResult\") as ButtonBase;\n            if (previousResultButton != null)\n            {\n                previousResultButton.Click += PreviousResultClicked;\n            }\n            var nextResultButton = GetTemplateChild(\"PART_NextResult\") as ButtonBase;\n            if (nextResultButton != null)\n            {\n                nextResultButton.Click += NextResultClicked;\n            }\n","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Presentation.Wpf/Controls/TextLogViewer.cs#L278-L314","documentation":"TextLogViewer requires its ControlTemplate to declare a part named 'PART_LogTextBox' of type RichTextBox, which hosts the rendered log content. OnApplyTemplate retrieves the part and throws InvalidOperationException when it is absent or of the wrong type, since the control cannot display logs without it. Unlike PART_ClearLog (optional), this part is mandatory.","triggerScenarios":"Assigning a custom ControlTemplate to TextLogViewer without an element named 'PART_LogTextBox', or where 'PART_LogTextBox' resolves to a non-RichTextBox element. Also when the default template cannot be resolved at apply-template time.","commonSituations":"Re-templating the log viewer for branding; copying the template but dropping or renaming the log area; upgrading the library and stale templates in resource dictionaries referencing older part names.","solutions":["Add <RichTextBox x:Name=\"PART_LogTextBox\"/> to the ControlTemplate for TextLogViewer.","Make sure the part is exactly a RichTextBox (not TextBox or RichTextBox derived hosted in another name).","Revert to the library's default template if you do not need custom visuals.","Optionally include the optional <ButtonBase x:Name=\"PART_ClearLog\"/> to keep the clear-log feature."],"exampleFix":"// before\n<ControlTemplate TargetType=\"controls:TextLogViewer\">\n  <TextBox x:Name=\"LogArea\"/>\n</ControlTemplate>\n// after\n<ControlTemplate TargetType=\"controls:TextLogViewer\">\n  <RichTextBox x:Name=\"PART_LogTextBox\" IsReadOnly=\"True\"/>\n</ControlTemplate>","handlingStrategy":"validation","validationCode":"var rtb = template.FindName(\"PART_LogTextBox\", scope) as RichTextBox;\nif (rtb == null) throw new InvalidOperationException(\"TextLogViewer template must contain RichTextBox named PART_LogTextBox\");","typeGuard":"bool HasLogTextBoxPart(FrameworkElement scope) => scope.FindName(\"PART_LogTextBox\", scope) is RichTextBox;","tryCatchPattern":"try { logViewer.ApplyTemplate(); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"PART_LogTextBox\")) { /* fall back to default template */ }","preventionTips":["Start custom TextLogViewer templates by copying the library's default template verbatim.","Keep the optional PART_ClearLog button when copying to preserve features.","Smoke-test ApplyTemplate in CI for every custom control template."],"tags":["wpf","control-template","template-parts"],"backgroundTag":"schema-validation-failed","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}