10

Sto legando IList a un GridView. IMyInterface assomigliaBinding IList <IMyInterfaceType> non visualizza membri di Interfacce ereditati da IMyInterface

public interface IMyInterface: IHasTotalHours, IHasLines 
{ 
    DateTime GoalStartDate { get; set; } 
    DateTime GoalEndDate { get; set; } 
} 

mi legano un'istanza a una griglia come questa:

IList<IMyInterface> instance= GetMyData(); 

myGrid.DataSource = instance; 
myGrid.DataBind(); 

Quando legare questo alla griglia, gli unici membri che compaiono nella griglia sono i membri diretti di IMyInterface: GoalStartDate e GoalEndDate.

Perché è quello? Come ottengo la griglia per visualizzare i membri delle altre interfacce che eredita?

Aggiornamento Le interfacce ereditate definiscono semplici proprietà dei dati come

public interface IHasTotalHours 
{ 
    string Description { get; set; } 
    int Hours{ get; set; } 
} 
public interface IHasLines 
{ 
    double TotalLines { get; set; } 
    double LinesPerHour { get; set; } 
} 

C'è una classe che implementa IMyInterface:

public class MyClass : IMyInterface 
{ 
    public string Description { get; set; } 
    public int Hours { get; set; } 
    public double TotalLines { get; set; } 
    public double LinesPerHour { get; set; } 
    public DateTime GoalStartDate { get; set; } 
    public DateTime GoalEndDate { get; set; } 

} 

Questi sono espressi come IMyInterface, e restituiti nell'elenco che Sono vincolante per GridView.

+0

Qual è la definizione per IHasTotalHours, IHasLines, IHasGoals? – shahkalpesh

+0

Inoltre, come appare la classe che implementa IMyInterface? – shahkalpesh

risposta

5

I controlli relativi ai dati non utilizzano la riflessione ma un TypeDescriptor per ottenere le proprietà da un'origine dati. Nel metodo TypeDescriptor.GetProperties, si può leggere quanto segue:

Le proprietà di un componente può differire dai proprietà di una classe, perché il sito può aggiungere o rimuovere proprietà se il componente è situata.

Apparentemente l'implementazione predefinita restituirà solo proprietà dirette da un'interfaccia e non da quelle ereditate.

Fortunatamente questo meccanismo è estensibile ed è possibile scrivere una classe TypeConverter con implementazione di informazioni sulle proprietà personalizzate. Fare riferimento alle osservazioni nella documentazione di TypeConverter per l'implementazione della logica di proprietà.

L'implementazione GetProperties della classe TypeConverter personalizzata può chiamare TypeDescriptor.GetProperties (Type) sull'interfaccia e tutte le sue interfacce ereditate. Ma forse potresti persino scrivere un TypeConverter generico che troverà tutte le proprietà ereditate usando la reflection.

Quindi si collega questo TypeConverter personalizzato all'interfaccia con l'attributo TypeConverterAttribute.

E quindi, come per magia, l'origine dati troverà tutte le proprietà. ;-)

+0

Eccellente. Questo è molto utile. Molte grazie! – jlembke

+1

Per completezza, TypeConverter si applica principalmente a cose come PropertyGrid; per le griglie, è più comune utilizzare ITypesList o TypeDescriptionProvider - o talvolta (meno comune) ICustomTypeDescriptor (sul 0 ° elemento) - ma raramente TypeConverter. –

0

È perché un'interfaccia è un contratto, e questo è l'unico modo per interagire con un oggetto tramite questo specifico contratto. Le altre interfacce non possono essere assunte e non possono essere utilizzate fino a quando non viene creato un cast.

Quindi quando si associa un elenco di T a qualcosa, il datagrid non sa di quelle altre interfacce. E il datagrid non userà la riflessione per capire quali altre classi o interfacce potrebbero essere ereditate. Le sole proprietà dell'oggetto che saranno disponibili per il datagrid sono le proprietà esposte dall'interfaccia T.

È necessario associare Elenco se si desidera che il datagrid abbia accesso a tutte le proprietà.

+0

Ma se una classe che implementa IMyInterface deve implementare anche i membri delle altre interfacce, non capisco perché quei membri non siano anche visibili. Non è in disaccordo con te. Nell'IDE quando passo il mouse sull'istanza, mi mostra solo i membri immediati. Devo scavare ulteriormente per vedere il resto. – jlembke

+0

Quindi stai dicendo che l'istanza dovrebbe essere List , non IList? Darò uno scatto al mattino. – jlembke

+0

Non fa differenza se si tratta di un elenco o IList. È il TIPO che conta. Il tipo IMyInterface espone SOLO due proprietà. Il datagrid non può conoscere gli altri perché è stato assegnato un tipo IMyInterface. –

Problemi correlati