のクラスがMyClass<MyObject>
あり、それを HierarchicalDataTemplate の DataType として設定したいと考えています。
XAML でのこれの構文は何ですか? (私は名前空間を設定する方法を知っています。
<HierarchicalDataTemplate DataType="{X:Type .....
のクラスがMyClass<MyObject>
あり、それを HierarchicalDataTemplate の DataType として設定したいと考えています。
XAML でのこれの構文は何ですか? (私は名前空間を設定する方法を知っています。
<HierarchicalDataTemplate DataType="{X:Type .....
itowlson のアプローチは良いものですが、それはほんの始まりにすぎません。あなたの場合(すべてではないにしても、ほとんどの場合)に役立つものを次に示します。
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;
}
}
次に、XAML で任意のレベルの深さを持つ任意の型を作成できます。例えば:
<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>
ここにはいくつかの重要なアイデアがあります。
これはそのままでは WPF 3.x ではサポートされていません (4.0 ではサポートされている可能性がありますが、よくわかりません)。マークアップ拡張機能を使用すると簡単に設定できます。
まず、型パラメーターをコンストラクター引数として受け取るマークアップ拡張クラスを作成する必要があります。
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);
}
}
x:Type 拡張機能の代わりに、このマークアップ拡張機能を使用します。
<HierarchicalDataTemplate DataType="{local:MyClassOf {x:Type MyObject}}" />
言うまでもなく、これを一般化して、任意のジェネリック型をインスタンス化できるようにすることができます。もう少し複雑になるので、これは示していません。
.NET 4.0 では、以下のコードを使用します。
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;