How to reference a generic type in the DataType attribute of a DataTemplate?
No, you cannot express a generics type in XAML. You will have to create a concrete type that extends your generic one ...
public class FooLocationTreeViewModel : LocationTreeViewModel<Foo>{}
In XAML 2006 this is not supported. You can, however, roll your own if you want to have this functionality.
This link has a nice tutorial on creating markup extensions.
Usage would be like this:
<Grid xmlns:ext="clr-namespace:CustomMarkupExtensions"> <TextBlock Text="{ext:GenericType FooLocationTreeViewModel(Of Foo)}" /></Grid>
You have to choose and implement the syntax though. I suggest the VB notation since it won't interfere like the C# notation does with < and >.
I know, that I'm a little late to the party, but I want post an answer for all those who may see this question in the future:
It is possible.
You can see the whole code in the answer to this question: DataTemplates and Generics. But since it is quite long, I will just copy the important bits. If you want more details, then look into the referenced question.
You need to write a
MarkupExtension
which can provide a closed generic type.public class GenericType : MarkupExtension{ public GenericType() { } public GenericType(Type baseType, params Type[] innerTypes) { BaseType = baseType; InnerTypes = innerTypes; } public Type BaseType { get; set; } public Type[] InnerTypes { get; set; } public override object ProvideValue(IServiceProvider serviceProvider) { Type result = BaseType.MakeGenericType(InnerTypes); return result; }}
Now you can define your type which closes your generic type in xaml, and then use the closed generic type as
DataType
of anDataTemplate
.<Window.Resources> <x:Array Type="{x:Type System:Type}" x:Key="ListWithTwoStringTypes"> <x:Type TypeName="System:String" /> <x:Type TypeName="System:String" /> </x:Array> <WpfApp1:GenericType BaseType="{x:Type TypeName=Generic:Dictionary`2}" InnerTypes="{StaticResource ListWithTwoStringTypes}" x:Key="DictionaryStringString" /> <DataTemplate DataType="{StaticResource DictionaryStringString}"> <TextBlock Text="Hi Dictionary" FontSize="40" Foreground="Cyan"/> </DataTemplate></Window.Resources>
Be happy that the defined
DataTemplate
gets automatically selected by WPF.