stride3d/stride · error · ArgumentException
Invalid '{templatePart.GetType().FullName}' TemplatePart typ
Error message
Invalid '{templatePart.GetType().FullName}' TemplatePart type. '{typeof(T).FullName}' expected. What it means
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.
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
Example fix
// before
var button = this.CheckTemplatePart<Button>(GetTemplateChild("PART_Action"));
// after
var button = this.CheckTemplatePart<ToggleButton>(GetTemplateChild("PART_Action")); Defensive patterns
Strategy: validation
Validate before calling
var part = GetTemplateChild("PART_Action");
if (part is not Button) throw new InvalidOperationException("PART_Action must be a Button"); // or fallback Type guard
T GetTypedPart<T>(object part) where T : class => part as T; // returns null instead of throwing
Try / catch
try { return this.CheckTemplatePart<Button>(GetTemplateChild("PART_Action")); }
catch (ArgumentException ex) when (ex.ParamName == "templatePart") { // re-type the template or log and degrade
return null; } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Behavior of type '{GetType()}' must be bound to objects of t
- The associated slider must have a Track child named 'PART_Tr
- The dependency object to attach to the DependencyPropertyWat
- {nameof(value)} is not a numeric type
- The parameter of the ConvertBack method of this converter mu
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/b34e685f5b558645.
Report an issue: GitHub.
Appendix: source
Thrown at sources/presentation/Stride.Core.Presentation.Wpf/Extensions/DependencyObjectExtensions.cs:195
d => LogicalTreeHelper.GetChildren(d).Cast<DependencyObject>().Count(),
(d, i) => LogicalTreeHelper.GetChildren(d).Cast<DependencyObject>().ElementAt(i));
}
/// <summary>
/// Checks that the given dependency object, retrieved as a template part of the calling object using <see cref="FrameworkElement.GetTemplateChild(string)"/>,
/// exists and matches the given type.
/// </summary>
/// <typeparam name="T">The type expected for the template part.</typeparam>
/// <param name="templatePart">The template part to evaluate.</param>
/// <returns>The given template part, cast into the proper type.</returns>
public static T CheckTemplatePart<T>(DependencyObject templatePart) where T : DependencyObject
{
if (templatePart == null)
return null;
if (templatePart is T == false)
{
throw new ArgumentException($"Invalid '{templatePart.GetType().FullName}' TemplatePart type. '{typeof(T).FullName}' expected.");
}
return (T)templatePart;
}
#region Helper methods
/// <summary>
/// Find the first parent that match the given type.
/// </summary>
/// <typeparam name="T">Type of parent to find.</typeparam>
/// <param name="source">Base node from where to start looking for parent.</param>
/// <param name="getParentFunc">Function that provide the parent element.</param>
/// <returns>Returns the retrieved parent, or null otherwise.</returns>
[CanBeNull]
private static T FindParentOfType<T>(DependencyObject source, [NotNull] Func<DependencyObject, DependencyObject> getParentFunc) where T : DependencyObject
{
if (source == null) throw new ArgumentNullException(nameof(source));View on GitHub (pinned to 96fad776d2)