绑定 IList<IMyInterfaceType> 无法显示 IMyInterface 继承的接口成员

14

我正在将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。


IHasTotalHours,IHasLines,IHasGoals的定义是什么? - shahkalpesh
还有,实现IMyInterface接口的类是什么样子的? - shahkalpesh
2个回答

7
数据绑定控件不使用反射,而是使用TypeDescriptor从数据源获取属性。在TypeDescriptor.GetProperties方法中,您可以读取以下内容:
组件的属性可能与类的属性不同,因为如果组件被定位,站点可以添加或删除属性。
显然,默认实现仅从接口返回直接属性,而不是继承的属性。
幸运的是,这种机制是可扩展的,您可以编写一个TypeConverter类,其中包含自定义属性信息实现。请参阅TypeConverter文档中的备注以实现属性逻辑。
您自定义TypeConverter类的GetProperties实现可以在您的接口及其所有继承的接口上调用TypeDescriptor.GetProperties(Type)。但是,您甚至可以编写通用TypeConverter,通过使用反射找到所有继承的属性。
然后,您可以使用TypeConverterAttribute属性将此自定义TypeConverter附加到您的接口上。
然后,就像魔法一样,数据源将找到所有属性。;-)

2
为了完整性,TypeConverter主要适用于PropertyGrid之类的东西;对于网格,更常见的是使用ITypesList或TypeDescriptionProvider - 或者有时(不太常见)使用ICustomTypeDescriptor(在第0项上)- 但很少使用TypeConverter。 - Marc Gravell

-1

这是因为接口是一种契约,而与对象交互的唯一方式就是通过该特定契约。其他接口不能被假定,也不能被利用,直到进行转换。

因此,当您将T列表绑定到某个东西时,数据网格不知道那些其他接口。数据网格也不会使用反射来确定可能继承的其他类或接口。数据网格可以访问的唯一对象属性是由T接口公开的属性。

如果您希望数据网格可以访问所有属性,则需要绑定List。


1
但是,如果实现IMyInterface的任何类也必须实现其他接口的成员,我不明白为什么那些成员也不可见。并不反对你的观点。在IDE中,当我悬停在实例上时,它只显示给我当前成员。我必须进一步查看才能看到其余成员。 - jlembke
那么你的意思是实例应该是List<IMyInterface>而不是IList?我明天会试一试。 - jlembke
无论是 List 还是 IList 都没有关系,重要的是类型。IMyInterface 类型只公开两个属性。数据网格不可能知道其他属性,因为它只接收一个 IMyInterface 类型。 - Chris Holmes
你可能需要了解接口和基类之间的区别。你所说的对于类继承是正确的,但对于接口并不是真实的情况。一个类并不会“继承”一个接口,而是实现它。这有着显著的区别。 - Chris Holmes
区别对于合同来说并不重要。如果“B 是 A”,那么 B 需要满足 A 的合同。无论 “是-a” 意味着“继承自”还是“实现接口”都没关系。 - Wim Coenen
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接