{"record":{"id":"b34e685f5b558645","repo":"stride3d/stride","slug":"invalid-templatepart-gettype-fullname-templatepart-type","errorCode":null,"errorMessage":"Invalid '{templatePart.GetType().FullName}' TemplatePart type. '{typeof(T).FullName}' expected.","messagePattern":"Invalid '(.+?)' TemplatePart type\\. '(.+?)' expected\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Presentation.Wpf/Extensions/DependencyObjectExtensions.cs","lineNumber":195,"sourceCode":"                d => LogicalTreeHelper.GetChildren(d).Cast<DependencyObject>().Count(),\n                (d, i) => LogicalTreeHelper.GetChildren(d).Cast<DependencyObject>().ElementAt(i));\n        }\n\n        /// <summary>\n        /// Checks that the given dependency object, retrieved as a template part of the calling object using <see cref=\"FrameworkElement.GetTemplateChild(string)\"/>,\n        /// exists and matches the given type.\n        /// </summary>\n        /// <typeparam name=\"T\">The type expected for the template part.</typeparam>\n        /// <param name=\"templatePart\">The template part to evaluate.</param>\n        /// <returns>The given template part, cast into the proper type.</returns>\n        public static T CheckTemplatePart<T>(DependencyObject templatePart) where T : DependencyObject\n        {\n            if (templatePart == null)\n                return null;\n\n            if (templatePart is T == false)\n            {\n                throw new ArgumentException($\"Invalid '{templatePart.GetType().FullName}' TemplatePart type. '{typeof(T).FullName}' expected.\");\n            }\n\n            return (T)templatePart;\n        }\n\n        #region Helper methods\n\n        /// <summary>\n        /// Find the first parent that match the given type.\n        /// </summary>\n        /// <typeparam name=\"T\">Type of parent to find.</typeparam>\n        /// <param name=\"source\">Base node from where to start looking for parent.</param>\n        /// <param name=\"getParentFunc\">Function that provide the parent element.</param>\n        /// <returns>Returns the retrieved parent, or null otherwise.</returns>\n        [CanBeNull]\n        private static T FindParentOfType<T>(DependencyObject source, [NotNull] Func<DependencyObject, DependencyObject> getParentFunc) where T : DependencyObject\n        {\n            if (source == null) throw new ArgumentNullException(nameof(source));","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Presentation.Wpf/Extensions/DependencyObjectExtensions.cs#L177-L213","documentation":"This ArgumentException is thrown by CheckTemplatePart<T> when the fetched template part exists but is not assignable to T. WPF templates can bind a part with a different concrete type than expected (e.g. a ToggleButton where a Button was expected), and this guard turns that mismatch into a descriptive error naming both the actual and expected types. It returns null (does not throw) when templatePart itself is null.","triggerScenarios":"Calling CheckTemplatePart<T>(part) where part came from FindName/Template.FindName inside a control template but its runtime type is not T, e.g. GetTemplateChild returned a Border but T is Button, usually after editing the control's default template or a derived style replaced a part.","commonSituations":"Custom control authors renaming or retyping template parts in Theme.xaml; third-party theme libraries overriding the default template with differently typed parts; version upgrades where a part's type changed.","solutions":["Fix the control template so the part named PART_... has the type the code expects","Change the generic argument T in CheckTemplatePart<T> to the actual type of the part (and adjust usage)","Add a type check on the part before use, or use as-cast with a null fallback for graceful degradation"],"exampleFix":"// before\nvar button = this.CheckTemplatePart<Button>(GetTemplateChild(\"PART_Action\"));\n// after\nvar button = this.CheckTemplatePart<ToggleButton>(GetTemplateChild(\"PART_Action\"));","handlingStrategy":"validation","validationCode":"var part = GetTemplateChild(\"PART_Action\");\nif (part is not Button) throw new InvalidOperationException(\"PART_Action must be a Button\"); // or fallback","typeGuard":"T GetTypedPart<T>(object part) where T : class => part as T; // returns null instead of throwing","tryCatchPattern":"try { return this.CheckTemplatePart<Button>(GetTemplateChild(\"PART_Action\")); }\ncatch (ArgumentException ex) when (ex.ParamName == \"templatePart\") { // re-type the template or log and degrade\n  return null; }","preventionTips":["Keep template part names and types in sync with the control code (x:Name PART_* conventions)","After editing a control template, re-verify each part's concrete type against CheckTemplatePart<T>","Use as-cast (part as T) with a null fallback when a wrong part type is acceptable to degrade","Pin theme/template library versions; review part type changes on upgrades"],"tags":["wpf","template","type-mismatch"],"backgroundTag":"type-mismatch","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"}