2012-04-04 6 views
13

Ich habe ein Ansichtsmodell wie folgt definiert:Wie wird auf einen generischen Typ im DataType-Attribut eines DataTemplate verwiesen?

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

Ich will es in dem Datatype-Attribute eines Datatemplate in XAML verweisen. Wie kann ich das machen?

+0

möglich Duplikat [Kann ich einen generischen Typ in XAML angeben?] (Http://stackoverflow.com/questions/185349/can-i-specify-a-generic-type-in-xaml) – franssu

Antwort

-2

Die einzige Möglichkeit, dies zu tun, ist MarkupExtensions zu verwenden.

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

Und, es zu benutzen Ich brauche nur, dies zu tun:

<DataTemplate DataType="{app:GenericType app:TreeBaseClass}"> 
+1

Es ist eine schlechte Lösung, da es mit der LocationTreeViewModel-Klasse gekoppelt ist .. – franssu

+0

@franssu: Danke für Ihren Kommentar, aber ich verstehe nicht, was du meinst? Ich wollte dies nicht für jede generische Klassen verwenden, ich don glaube nicht, dass es überhaupt möglich ist! Haben Sie eine bessere Lösung? –

+1

-1: Leider löst dies einen MC-Fehler aus; 'DataType'' 'DataType' kann nur einen vordefinierten Satz von Erweiterungen akzeptieren [zB' x: Type']. Suck up [@ ColinEs Antwort] (http://stackoverflow.com/a/10005490/11635) war meine Schlussfolgerung –

8

Nein, Sie können keinen generischen Typ in XAML ausdrücken. Sie müssen einen konkreten Typ erstellen, der Ihren generischen Wert erweitert ...

+0

Ich habe diese Technik mit Erfolg benutzt, aber letztendlich habe ich einen generischen Wrapper erstellt, siehe meine Antwort, die sich auf dieses Thema bezieht: http://stackoverflow.com/a/33827448/11635 –

3

In XAML 2006 wird dies nicht unterstützt. Sie können jedoch Ihre eigenen rollen, wenn Sie diese Funktionalität haben möchten.

This link hat ein nettes Tutorial zum Erstellen von Markup-Erweiterungen.

Verbrauch würde so aussehen:

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

Sie haben die Syntax allerdings wählen und zu implementieren. Ich schlage die VB-Notation vor, da sie nicht wie die C# -Notation mit < und> interferiert.

+2

wird nicht als 'DataType'-Bit eines' DataTemplate' funktionieren nicht erlaubt Markup-Erweiterungen –

-1

Leicht verbesserte Version von Markupextension, Arbeit für die Klassen bis zu 3 allgemeine Parameter.

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

Dies beantwortet nicht das OP - keine Verwendung für Datatemplates –

Verwandte Themen