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

StackOverflow https://stackoverflow.com/questions/539568

Вопрос

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

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

Я привязываю экземпляр к Grid следующим образом:

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.

Это было полезно?

Решение

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

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

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

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

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

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

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

Другие советы

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top