我有一个类,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;