7

のクラスがMyClass<MyObject>あり、それを HierarchicalDataTemplate の DataType として設定したいと考えています。

XAML でのこれの構文は何ですか? (私は名前空間を設定する方法を知っています。

<HierarchicalDataTemplate DataType="{X:Type .....
4

3 に答える 3

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<>System.Collections.Generic.List`1です。文字 ` は型がジェネリックであることを示し、その後の数字は型が持つジェネリック パラメーターの数を示します。
  • x:Type マークアップ拡張機能は、これらの基本ジェネリック型を非常に簡単に取得できます。
  • ジェネリック パラメーターの型は、Type オブジェクトの配列として渡されます。次に、この配列が MakeGenericType(...) 呼び出しに渡されます。
于 2009-11-10T15:20:45.287 に答える
4

これはそのままでは 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}}" />

言うまでもなく、これを一般化して、任意のジェネリック型をインスタンス化できるようにすることができます。もう少し複雑になるので、これは示していません。

于 2009-11-10T07:24:36.513 に答える
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

于 2011-03-23T09:53:05.780 に答える