I have a class of MyClass<MyObject>
and want to set it as the DataType for a HierarchicalDataTemplate.
What is the syntax for this in XAML? (I know how to set namespaces, I need just the syntax for
<HierarchicalDataTemplate DataType="{X:Type .....
itowlson's approach is a good one but it is just a start. Here's something that will work for your case (and most, if not all, cases):
public class GenericType : MarkupExtension
{
public Type BaseType { get; set; }
public Type[] InnerTypes { get; set; }
public GenericType() { }
public GenericType(Type baseType, params Type[] innerTypes)
{
BaseType = baseType;
InnerTypes = innerTypes;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
Type result = BaseType.MakeGenericType(InnerTypes);
return result;
}
}
Then, you are able to create any type with any level of depth in your XAML. For example:
<Grid.Resources>
<x:Array Type="{x:Type sys:Type}"
x:Key="TypeParams">
<x:Type TypeName="sys:Int32" />
</x:Array>
<local:GenericType BaseType="{x:Type TypeName=coll:List`1}"
InnerTypes="{StaticResource TypeParams}"
x:Key="ListOfInts" />
<x:Array Type="{x:Type sys:Type}"
x:Key="DictionaryParams">
<x:Type TypeName="sys:Int32" />
<local:GenericType BaseType="{x:Type TypeName=coll:List`1}"
InnerTypes="{StaticResource TypeParams}" />
</x:Array>
<local:GenericType BaseType="{x:Type TypeName=coll:Dictionary`2}"
InnerTypes="{StaticResource DictionaryParams}"
x:Key="DictionaryOfIntsToListOfInts" />
</Grid.Resources>
There's a few key ideas here:
This is not supported in WPF 3.x out of the box (I think it may be in 4.0, but I'm not sure); but it's easy to set up with a markup extension.
First, you need to create a markup extension class that takes the type parameter as a constructor argument:
public class MyClassOf : MarkupExtension
{
private readonly Type _of;
public MyClassOf(Type of)
{
_of = of;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return typeof(MyClass<>).MakeGenericType(_of);
}
}
Now you use this markup extension in place of the x:Type extension:
<HierarchicalDataTemplate DataType="{local:MyClassOf {x:Type MyObject}}" />
Needless to say, this can be generalised to allow instantiation of arbitrary generic types; I haven't shown this because it adds a wee bit more complexity.
In .NET 4.0, use below code.
XamlNamespaceResolver nameResolver = serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlNamespaceResolver;
IXamlSchemaContextProvider schemeContextProvider = serviceProvider.GetService(typeof(IXamlSchemaContextProvider)) as IXamlSchemaContextProvider;
XamlTypeName xamlTypeName = new XamlTypeName(nameResolver.GetNamespace("generic"), "List`1");
Type genericType = schemeContextProvider.SchemaContext.GetXamlType(xamlTypeName).UnderlyingType;
http://illef.tistory.com/115
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With