Generics in XAML
The .NET Framework XAML Services as implemented in System.Xaml provides support for using generic CLR types. This support includes specifying the constraints of generics as a type argument and enforcing the constraint by calling the appropriate Add method for generic collection cases. This topic describes aspects of using and referencing generic types in XAML.
x:TypeArguments is a directive defined by the XAML language. When it is used as a member of a XAML type that is backed by a generic type, x:TypeArguments passes constraining type arguments of the generic to the backing constructor. For reference syntax that pertains to .NET Framework XAML Services use of x:TypeArguments, which includes syntax examples, see x:TypeArguments Directive.
Because x:TypeArguments takes a string, and has type converter backing, it is typically declared in XAML usage as an attribute.
In the XAML node stream, the information declared by x:TypeArguments can be obtained from XamlType.TypeArguments at a StartObject position in the node stream. The return value of XamlType.TypeArguments is a list of XamlType values. Determination of whether a XAML type represents a generic type can be made by calling XamlType.IsGeneric.
In XAML, a generic type must always be represented as a constrained generic; an unconstrained generic is never present in the XAML type system or a XAML node stream and cannot be represented in XAML markup. A generic can be referenced within XAML attribute syntax, for cases where it is a nested type constraint of a generic being referenced by x:TypeArguments, or for cases where x:Type supplies a CLR type reference for a generic type. This is supported through the XamlTypeTypeConverter class defined by .NET Framework XAML Services.
The XAML attribute syntax form enabled by XamlTypeTypeConverter alters the typical MSIL / CLR syntax convention that uses angle brackets for types and constraints of generics, and instead substitutes parentheses for the constraint container. For an example, see x:TypeArguments Directive.
If you use XAML 2009 instead of mapping the CLR base types to obtain XAML types for common language primitives, you can use XAML 2009 built-in types as information items in x:TypeArguments. For example, you could declare the following (prefix mappings not shown, but x is the XAML language XAML namespace for XAML 2009):
For XAML 2006 usage when specifically targeting WPF, x:Class must also be provided on the same element as x:TypeArguments, and that element must be the root element in a XAML document. The root element must map to a generic type with at least one type argument. An example is PageFunction<T>.
Possible workarounds to support generic usages include defining a custom markup extension that can return generic types, or providing a wrapping class definition that derives from a generic type but flattens the generic constraint in its own class definition.
In WPF and targeting .NET Framework 4, you can use XAML 2009 features together with x:TypeArguments, but only for loose XAML (XAML that is not markup-compiled). Markup-compiled XAML for WPF and the BAML form of XAML do not currently support the XAML 2009 keywords and features.
Custom workflows in Windows Workflow Foundation for .NET Framework 3.5 do not support generic XAML usage.