27

次のように定義された ViewModel があります。

public class LocationTreeViewModel<TTree> : 
    ObservableCollection<TTree>, INotifyPropertyChanged
        TTree : TreeBase<TTree>

XAMLDataTypeのaの属性で参照したい。DataTemplateどうやってやるの?

4

9 に答える 9

16

いいえ、XAML でジェネリック型を表現することはできません。ジェネリック型を拡張する具象型を作成する必要があります...

public class FooLocationTreeViewModel : LocationTreeViewModel<Foo>
{
}
于 2012-04-04T05:38:41.617 に答える
3

XAML 2006 では、これはサポートされていません。ただし、この機能が必要な場合は、独自のロールを作成できます。

このリンクには、マークアップ拡張機能の作成に関する優れたチュートリアルがあります。

使用法は次のようになります。

<Grid xmlns:ext="clr-namespace:CustomMarkupExtensions">
  <TextBlock Text="{ext:GenericType FooLocationTreeViewModel(Of Foo)}" />
</Grid>

ただし、構文を選択して実装する必要があります。C# 表記法が < および > で行うように干渉しないため、VB 表記法をお勧めします。

于 2012-04-04T05:46:05.573 に答える
-2

MarkupExtension のわずかに改良されたバージョンで、最大 3 つのジェネリック パラメータで動作します。

  public class GenericTypeExtension : MarkupExtension
  {
    public GenericTypeExtension()
    {

    }
    public GenericTypeExtension(string baseTypeName_, Type genericType1_, Type genericType2_, Type genericType3_)
    {
      BaseTypeName = baseTypeName_;
      GenericType1 = genericType1_;
      GenericType2 = genericType2_;
      GenericType3 = genericType3_;
    }
    public string BaseTypeName { get; set; }
    public string BaseTypeAssemblyName { get; set; }
    public Type GenericType1 { get; set; }
    public Type GenericType2 { get; set; }
    public Type GenericType3 { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider_)
    {
      var list = new List<Type>();
      if (GenericType1 != null)
      {
        list.Add(GenericType1);
      }
      if (GenericType2 != null)
      {
        list.Add(GenericType2);
      }
      if (GenericType3 != null)
      {
        list.Add(GenericType3);
      }

      var type = Type.GetType(string.Format("{0}`{1}, {2}", BaseTypeName, list.Count, BaseTypeAssemblyName));
      if (type != null)
      {
        return type.MakeGenericType(list.ToArray());
      }
      return null;
    }

  }
于 2015-01-22T10:27:46.920 に答える
-2

これを行う唯一の方法は、を使用することMarkupExtensionsです。

public class GenericType : MarkupExtension
{
     private readonly Type _of;
     public GenericType(Type of)
     {
         _of = of;
     }
     public override object ProvideValue(IServiceProvider serviceProvider)
     {
         return typeof(LocationTreeViewModel<>).MakeGenericType(_of);
     }
}

そしてそれを使用するには、これを行う必要があります:

<DataTemplate DataType="{app:GenericType app:TreeBaseClass}">
于 2013-12-12T12:42:04.540 に答える