2014-12-19 8 views
5

ho definito una consuetudine ExpandableObjectConverter per le collezioni:Aggiungere i descrittori di tipi a tutti gli elenchi <T> per un'implementazione generica dell'espansione della griglia di proprietà?

internal class ExpandableCollectionConverter : ExpandableObjectConverter 
{ 
    public override PropertyDescriptorCollection GetProperties(
     ITypeDescriptorContext context, object value, Attribute[] attributes) 
    { 
     //implementation that returns a list of property descriptors, 
     //one for each item in "value" 
    } 
} 

E hanno anche una classe proxy chiamato ExpandableObjectManager, che in sostanza fa questo:

TypeDescriptor.AddAttributes(type, 
    new TypeConverterAttribute(typeof(ExpandableCollectionConverter))); 

Utilizzando questo metodo:

public static class ExpandableObjectManager 
{ 
    public static void AddTypeDescriptor(Type tItem) 
    { 
     //eventually calls TypeDescriptor.AddAttributes 
    } 
} 

È possibile aggiungere il descrittore di tipo in modo tale che tutti i generici List<T> siano espandibili nella prope griglia? Ad esempio, dato un semplice Employee classe:

class Employee 
{ 
    public string Name { get; set; } 
    public string Title { get; set; } 
    public DateTime DateOfBirth { get; set; } 
} 

posso fare questo (e funziona, ma solo per List<Employee>):

ExpandableObjectManager.AddTypeDescriptor(typeof(List<Employee>)); 

Vorrei coprire tutte T, non solo Employee, senza dover scrivere 1 riga per ogni classe possibile. Ho provato questo - non ha funzionato:

ExpandableObjectManager.AddTypeDescriptor(typeof(List<>)); 

TL; DR: Vista predefinita di un elenco quando impostato come SelectedObject nella griglia delle proprietà:

enter image description here

risultati attesi :

enter image description here

Senza dover aggiungere un descrittore di tipo per List<Employee> e avere invece un gestore generico per tutti List<T>.

risposta

2

Modifica: ho aggiunto una terza possibilità.

non credo che nessuna di queste sono soluzioni meravigliose ma qui ci sono tre possibilità:

Aggiungi TypeConverterAttribute a un'interfaccia che il tipo di attrezzi generici. Il rovescio della medaglia qui è che potresti non colpire con precisione i tipi che stai mirando, ma è meglio dell'opzione 2 perché è un po 'più focalizzata sui tipi che desideri.

TypeDescriptor.AddAttributes(typeof(IList), new 
    TypeConverterAttribute(typeof(ExpandableCollectionConverter))); 

Aggiungere il TypeConverterAttribute al tipo object. Lo svantaggio è che questo renderà il tuo convertitore di tipi il convertitore di tipi per tutti i tipi nel tuo progetto.

TypeDescriptor.AddAttributes(typeof(object), new 
    TypeConverterAttribute(typeof(ExpandableCollectionConverter))); 

creare un tipo di lista che eredita da List<> e lo hanno in sé registrare nel costruttore statico

public class CustomList<T> : List<T> 
{ 
    static CustomList() 
    { 
     TypeDescriptor.AddAttributes(typeof(CustomList<T>), new TypeConverterAttribute(typeof(ExpandableCollectionConverter))); 
    } 
} 
+0

Grazie per la risposta. Sfortunatamente, nessuna delle due opzioni funziona per me, perché # 1 alcuni oggetti hanno già una buona implementazione di un convertitore di oggetti espandibile, che io avrei interrotto, se avessi impostato il mio. Ad esempio, enum.# 2 Non voglio creare una classe personalizzata per rappresentare l'elenco . Aggiunge complessità non necessaria al programma. Anche gli assiemi esistenti non possono usarlo. – Neolisk

+1

Totalmente comprensibile. Se trovo un'opzione migliore, la condividerò. – Grax

+0

Ho aggiunto una terza opzione. L'ho elencato per primo perché sembra ancora il più praticabile. – Grax

Problemi correlati