7

¿Hay alguna manera de crear una plantilla de datos que maneje una lista de elementos?DataTemplate.DataType = Colección <Entity>?

que tienen Contact.Phones (EntityCollection<Phone>) y quiero que la plantilla de datos para manejar la lista - Agregar Quitar editar etc.

¿Hay una manera de establecer la propiedad Tipo de datos de la DataTemplate a EntityCollection<Phone> genérica?

Respuesta

7

En mi herramienta Emerald Data Foundation (EDF) resolví esto creando una MarkupExtension más poderosa que x: Tipo que también podría especificar tipos genéricos. De esa manera podría escribir:

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

Esto es lo que he usado:

[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+)*)>$"); 

    } 

El nombre de tipo genérico código de análisis está en un método separado, ya que también es utilizado por algún otro código de FED. Puedes combinar todo en un método.

Cuestiones relacionadas