2012-04-04 183 views
13

我有這樣定義的視圖模型:如何在DataTemplate的DataType屬性中引用泛型類型?

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

我想引用它在XAML一個DataTemplate的數據類型屬性。我怎樣才能做到這一點?

+0

的可能重複[我可以指定XAML泛型類型?(http://stackoverflow.com/questions/185349/can-i-specify-a-generic-type-in​​-xaml) – franssu 2014-04-03 09:54:32

回答

-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}"> 
+1

這是一個糟糕的解決方案,因爲它與LocationTreeViewModel類耦合在一起.. – franssu 2014-04-03 09:51:07

+0

@franssu:感謝您的評論,但我不明白你的意思?我不想爲每個泛型類使用它,我不想不要認爲它是可能的! 你有更好的解決方案嗎? – 2014-10-13 08:31:32

+1

-1:不幸的是,這會觸發MC錯誤; DataTemplate的'DataType'只能接受一組預定義的擴展[例如'x:Type']。吸取[@ ColinE的回答](http://stackoverflow.com/a/10005490/11635)是我的結論 – 2015-11-20 11:54:35

8

不,您不能在XAML中表示泛型類型。你將不得不創建一個擴展您的泛型一個具體類型...

public class FooLocationTreeViewModel : LocationTreeViewModel<Foo> 
{ 
} 
+0

我用這種技術取得了成功,但最終[構建了一個通用包裝器,請參閱我的回答,在此詳細解釋](http://stackoverflow.com/a/33827448/11635) – 2015-11-20 13:11:14

3

2006年XAML不支持此操作。但是,如果您想擁有此功能,您可以推出自己的產品。

This link有關於創建標記擴展的一個很好的教程。

用法是這樣的:

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

你必須選擇,雖然實現的語法。我建議VB符號,因爲它不會像C#符號那樣干擾<和>。

+2

不會用作'DataTemplate'的'DataType'位不允許標記擴展 – 2015-11-20 13:12:27

-1

的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; 
    } 

    } 
+0

這不回答OP - 沒有用於數據類型 – 2015-11-20 13:13:19