Привязка IList<IMyInterfaceType> не отображает элементы интерфейсов, которые наследует IMyInterface.
-
22-08-2019 - |
Вопрос
Я привязываю 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, если вы хотите, чтобы сетка данных имела доступ ко всем свойствам.