如何在导出List <T>的类中数据绑定到与列表项无关的属性

LJ.*_*LJ. 4 c# generics data-binding

以前,我有一个包含内部System.Collections.Generic.List<Item>的类(其中Item是我创建的类).包装器类提供了几个集合级属性,这些属性提供了列表中项目的总计,平均值和其他计算.我正在创建一个BindingSource围绕这个包装List<>和另一个BindingSource围绕我的类,并能够通过第一个BindingSource和包装类的集合级属性使用第二个来获取包装列表中的Items .

一个简化的例子如下:

public class OldClass()
{
  private List<Item> _Items;

  public OldClass()
  {
    _Items = new List<Item>();
  }

  public List<Item> Items { get { return _Items; } }

  // collection-level properties
  public float AverageValue { get { return Average() } }
  public float TotalValue { get { return Total() } }
  // ... other properties like this

}
Run Code Online (Sandbox Code Playgroud)

使用以这种方式创建的绑定源:

_itemsBindingSource = new BindingSource(oldClass.Items);
_summaryBindingSource = new BindingSource(oldClass);
Run Code Online (Sandbox Code Playgroud)

最近,我尝试将此类更改为派生System.Collections.Generic.List<Item>而不是保留包装List<>成员.我希望摆脱额外的包装层,只使用一个BindingSource而不是两个.但是,现在我发现AverageValue当我进行数据绑定时,我无法获取适用于列表中所有项目的属性(例如).只有列表项的属性可用.

我被迫回去使用包裹List<>Items?或者有没有办法可以获得Item存储我的新类的属性以及适用于集合本身的属性?

Mar*_*ell 6

系统将实现IList(或IListSource)的任何东西视为容器,而不是项目.因此,您无法绑定到任何实现的属性IList.因此,如果您希望能够绑定到容器的属性,则封装(即您已经拥有的)是最好的方法.

但是,您应该注意到许多绑定支持源中的点符号 - 即绑定到"Items.SomeProperty",或设置辅助属性(通常DataMember)以指定子列表.

这允许你有一个单独的BindingSource,并且有不同的控件绑定到层次结构中的不同级别 - 即你可能有一个TextBox绑定AverageValue,和一个DataGridView(具有相同DataSource)绑定DataMember="Items".