Binding IList <IMyInterfaceType> не отображает элементы интерфейсов, которые наследует IMyInterface

Я связываю IList с GridView. IMyInterface выглядит как

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

Я связываю экземпляр с сеткой, как это:

IList<IMyInterface> instance= GetMyData();

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

При привязке этого к сетке единственными членами, которые отображаются в сетке, являются прямые члены IMyInterface: GoalStartDate и GoalEndDate.

Почему? Как получить сетку для отображения элементов других интерфейсов, которые она наследует?

Обновление Наследуемые интерфейсы определяют простые свойства данных, такие как

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

Существует класс, который реализует 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; }

}

Они отображаются как IMyInterface и возвращаются в список, который я привязываю к GridView.

Ответ 1

Элементы управления, привязанные к данным, не используют отражение, а TypeDescriptor для получения свойств из источника данных. В методе TypeDescriptor.GetProperties вы можете прочитать следующее:

Свойства для компонента могут отличаются от свойств класса, потому что сайт может добавлять или удалять свойства, если компонент указан.

По-видимому, реализация по умолчанию возвращает только прямые свойства из интерфейса, а не унаследованные.

К счастью, этот механизм расширяем, и вы можете написать класс TypeConverter с реализацией информации об пользовательских свойствах. Пожалуйста, обратитесь к примечаниям в документации TypeConverter для реализации логики свойств.

Реализация GetProperties вашего настраиваемого класса TypeConverter может вызывать TypeDescriptor.GetProperties(Тип) на вашем интерфейсе и все его унаследованные интерфейсы. Но, возможно, вы даже можете написать общий TypeConverter, который найдет все унаследованные свойства, используя отражение.

Затем вы присоединяете этот настраиваемый TypeConverter к вашему интерфейсу с помощью атрибута TypeConverterAttribute.

И затем, подобно магии, источник данных найдет все свойства.; -)

Ответ 2

Это потому, что интерфейс является контрактом и что единственный способ взаимодействия с объектом - через этот конкретный контракт. Другие интерфейсы не могут быть приняты и не могут быть использованы до тех пор, пока не будет выполнено литье.

Поэтому, когда вы привязываете List of T к чему-то, datagrid не знает об этих других интерфейсах. И datagrid не собирается использовать рефлексию, чтобы выяснить, какие другие классы или интерфейсы могут быть унаследованы. Единственными свойствами объекта, которые будут доступны для datagrid, являются свойства, отображаемые интерфейсом T.

Вам нужно связать List, если вы хотите, чтобы datagrid имел доступ ко всем свойствам.