如何在HierarchicalDataTemplate的DataType属性中引用泛型类型?

时间:2009-11-10 07:12:25

标签: .net wpf xaml hierarchicaldatatemplate

我有一个MyClass<MyObject>类,并希望将其设置为HierarchicalDataTemplate的DataType。

XAML中的语法是什么? (我知道如何设置命名空间,我只需要

的语法
<HierarchicalDataTemplate DataType="{X:Type .....

3 个答案:

答案 0 :(得分:16)

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>

这里有一些关键的想法:

  • 必须使用标准符号指定泛型类型。因此, System.Collections.Generic.List&lt;&gt; System.Collections.Generic.List`1 。字符`表示该类型是通用的,后面的数字表示该类型具有的通用参数的数量。
  • x:类型标记扩展能够非常轻松地检索这些基本泛型类型。
  • 泛型参数类型作为Type对象的数组传递。然后将此数组传递给MakeGenericType(...)调用。

答案 1 :(得分:4)

WPF 3.x开箱即用不支持(我认为它可能在4.0中,但我不确定);但是使用标记扩展名很容易设置。

首先,您需要创建一个标记扩展类,它将type参数作为构造函数参数:

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}}" />

不用说,这可以推广到允许任意泛型类型的实例化;我没有表现出来,因为它增加了一点点复杂性。

答案 2 :(得分:1)

在.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;

http://illef.tistory.com/115