dotnet/wpf · error · ArgumentException
SR.UnexpectedParameterType
Error message
SR.UnexpectedParameterType
What it means
Decorator's explicit IAddChild.AddChild implementation rejects any value that is not a UIElement. WPF XAML parsing calls this method when assigning the child element, so passing a non-visual object as the Decorator's child triggers ArgumentException with the UnexpectedParameterType message. Decorator can only host visual children, hence the strict type requirement.
Solutions
- Ensure the object passed as the Decorator child derives from System.Windows.UIElement
- Wrap non-visual content in a UIElement host (e.g. ContentControl or TextBlock) before adding
- Fix the XAML so only element syntax (not raw text/data) appears inside the Decorator
- If a data item is intended, bind it to Content of a ContentControl instead of adding directly
Example fix
// before
border.AddChild(new MyViewModel());
// after
border.AddChild(new ContentControl { Content = new MyViewModel() }); Defensive patterns
Strategy: type-guard
Validate before calling
if (!(value is UIElement)) throw new ArgumentException(nameof(value));
Type guard
bool IsValidChild(object v) => v is UIElement;
Try / catch
try { ((IAddChild)decorator).AddChild(value); }
catch (ArgumentException ex) { /* value was not a UIElement */ } Prevention
- Only pass UIElement-derived objects as Decorator children
- Prefer the strongly-typed Child property over IAddChild.AddChild
- In XAML, place only element syntax inside Decorator-derived tags
When it happens
Trigger: Calling IAddChild.AddChild explicitly with a non-UIElement object, or XAML markup that places a non-UIElement (e.g. a string or POCO) directly inside a Border, Viewbox, or other Decorator-derived element.
Common situations: XAML typos placing plain text or data objects as the direct child of a Border; programmatic code casting errors where an object is assumed to be a UIElement but is not; binding a non-visual object into Content where the template uses a Decorator.
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
- SR.CanOnlyHaveOneChild
- SR.CanOnlyHaveOneChild
- SR.Format(SR.ParserPrefixNSProperty, nsPrefix, nameString)
- SR.NameScopeNameNotFound
- SR.ParserAttributeArgsLow
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/a9d36199be0284ad.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Decorator.cs:65
// Public Methods
//
//-------------------------------------------------------------------
#region Public Methods
///<summary>
/// This method is called to Add the object as a child of the Decorator. This method is used primarily
/// by the parser; a more direct way of adding a child to a Decorator is to use the <see cref="Child" />
/// property.
///</summary>
///<param name="value">
/// The object to add as a child; it must be a UIElement.
///</param>
void IAddChild.AddChild (Object value)
{
if (!(value is UIElement))
{
throw new ArgumentException (SR.Format(SR.UnexpectedParameterType, value.GetType(), typeof(UIElement)), nameof(value));
}
if (this.Child != null)
{
throw new ArgumentException(SR.Format(SR.CanOnlyHaveOneChild, this.GetType(), value.GetType()));
}
this.Child = (UIElement)value;
}
///<summary>
/// This method is called by the parser when text appears under the tag in markup.
/// As Decorators do not support text, calling this method has no effect if the text
/// is all whitespace. For non-whitespace text, throw an exception.
///</summary>
///<param name="text">
/// Text to add as a child.
///</param> View on GitHub (pinned to 81131a70a4)