7

Gibt es eine Möglichkeit, eine Datenvorlage zu erstellen, die eine Liste von Elementen behandelt?DataTemplate.DataType = Sammlung <Entity>?

Ich habe Contact.Phones (EntityCollection<Phone>) und ich möchte, dass die Datenvorlage, die Liste zu handhaben - add remove bearbeiten usw.

Gibt es eine Möglichkeit, die Datatype-Eigenschaft des Datatemplate auf generische EntityCollection<Phone> zu setzen?

Antwort

7

In meinem Emerald Data Foundation (EDF) Tool habe ich dies gelöst, indem ich eine leistungsfähigere MarkupExtension als x: Type erstellt habe, die auch generische Typen angeben kann. So kann ich schreiben konnte:

<DataTemplate TargetType="{edf:Type generic:ICollection{local:Entity}}" /> 

Hier ist, was ich verwenden:

[MarkupExtensionReturnType(typeof(Type))] 
    public class TypeExtension : MarkupExtension 
    { 
    public TypeExtension() { } 
    public TypeExtension(string typeName) { TypeName = typeName; } 
    public TypeExtension(Type type) { Type = type; } 

    public string TypeName { get; set; } 
    public Type Type { get; set; } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     if(Type==null) 
     { 
     IXamlTypeResolver typeResolver = serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlTypeResolver; 
     if(typeResolver==null) throw new InvalidOperationException("EDF Type markup extension used without XAML context"); 
     if(TypeName==null) throw new InvalidOperationException("EDF Type markup extension used without Type or TypeName"); 
     Type = ResolveGenericTypeName(TypeName, (name) => 
     { 
      Type result = typeResolver.Resolve(name); 
      if(result==null) throw new Exception("EDF Type markup extension could not resolve type " + name); 
      return result; 
     }); 
     } 
     return Type; 
    } 

    public static Type ResolveGenericTypeName(string name, Func<string, Type> resolveSimpleName) 
    { 
     if(name.Contains('{')) 
     name = name.Replace('{', '<').Replace('}', '>'); // Note: For convenience working with XAML, we allow {} instead of <> for generic type parameters 

     if(name.Contains('<')) 
     { 
     var match = _genericTypeRegex.Match(name); 
     if(match.Success) 
     { 
      Type[] typeArgs = (
      from arg in match.Groups["typeArgs"].Value.SplitOutsideParenthesis(',') 
      select ResolveGenericTypeName(arg, resolveSimpleName) 
      ).ToArray(); 
      string genericTypeName = match.Groups["genericTypeName"].Value + "`" + typeArgs.Length; 
      Type genericType = resolveSimpleName(genericTypeName); 
      if(genericType!=null && !typeArgs.Contains(null)) 
      return genericType.MakeGenericType(typeArgs); 
     } 
     } 
     return resolveSimpleName(name); 
    } 
    static Regex _genericTypeRegex = new Regex(@"^(?<genericTypeName>\w+)<(?<typeArgs>\w+(,\w+)*)>$"); 

    } 

Der generische Typ Name Parsing-Code in einem separaten Verfahren, weil es auch von einigen anderen Code in EDF verwendet wird. Sie könnten alles zu einer Methode kombinieren.

Verwandte Themen